Passing multiple parameters in Pages

I am trying to get multiple parameters in a page.
For now I am trying with 2 only. I manage to recover my first parameter but could not access my second parameter.
I am following the cattr example of Fuse, But there are only one parameter involve in the example.

So far I have:

In the ux file that calls the next page :

<DockPanel>
	<Navigator ux:Name="navigator" DefaultPath="startPage">
		<MyPage.Page ux:Template="tempPage" Parameter1="{parameter1}" Parameter2="{parameter2}" routerDiag="routerDiag"/>
	</Navigator>
</DockPanel>

In the js file that calls the next page :

function goNextPage() {
	routerDiag.push("pathologyDiagQuestion", { param1: parameter1, param2: parameter2 });
}

module.exports = {
	parameter1: this.Parameter.map(function(param) {
		return param.param1;
	}),
	parameter2: this.Parameter.map(function(param) {
		return param.param2;
	}),
        goNextPage : goNextPage
};

In the next page ux file :

<Page ux:Class="MyPage.Page">
	<string ux:Property="Parameter1" />
	<string ux:Property="Parameter2" />
        <Text ux:Class="myText.Text"  Value="{parameter1}"/>
        <Text ux:Class="myText.Text"  Value="{parameter2}"/>
</Page>

In the next page js file :

var parameter1 = this.Parameter1.map(function(param){
	 return param;
});

var parameter2 = this.Parameter2.map(function(param){
	 return param;
});
module.exports = {
	parameter1: parameter1,
	parameter2: parameter2,
};

It looks like you’re confusing (or at least mixing up) properties and router parameters.

ux:Property and router parameters are similar in the way how they both are accessed via implicit, derived Observables (see docs). This pattern implies reactive programming.

The point where you seem to hop out of the reactive paradigm is around here:

function goNextPage() {
	routerDiag.push("pathologyDiagQuestion", { param1: parameter1, param2: parameter2 });
}

There is no immediate problem with logic, but just a little oversight on your part. You can only pass serialisable objects via router (while ux:Property will happily accept Observables too). In your case, parameter1 and parameter2 are Observables (implicit, derived), so passing them like that in a router.push() is illegal.

You could try to see if changing your code to this helps solve your issue:

function goNextPage() {
	routerDiag.push("pathologyDiagQuestion", { param1: parameter1.value, param2: parameter2.value });
}

I still could not figure that out.
I think both my parameters are not the same type.
I basically took in your samples the cattr example (the one with the pet selection). And I tried to build on it taking for model the PetSelectionPage.js where I saw

var Backend = require("Backend.js");

module.exports = {
	pets: Backend.getPets().map(function(pet) {
		pet.mainPicture = pet.pictures[0];
		pet.clicked = function() {
			router.push("home", { pet: pet.name }, "details");
		}
		return pet;
	}),
};

I also took as a model the same Backend.js file

On that I applied what you saw previously where I tried to add a second parameter.
This second parameter I declare like this :

var parameter2 = Observable("");
function startDiag(parameter1) {
	parameter2.value = "1";
	routerDiag.push("pathologyDiagQuestion", { param1: parameter1.name, param2: parameter2.value });

}

Note that parameters1.name is in the same logic as in your cattr example.

We won’t be able to help without seeing a complete, minimal reproduction that we can copy-paste and run.

Add console.log() calls in all applicable places and debug what you have there.

@Uldis
I have seen in other post that people could upload their code on a dropbox file. Would that be more convenient?

Not in this case I reckon, because your challenge appears to be somewhat basic. You should first debug it yourself, and try to create a minimal reproduction (a single-UX-file app).

That dropbox place is a last resort when all else fails with debugging complicated issues in projects that are sensitive and can’t be shared in public.

If you still fail isolating the cause of your issues, I believe you can easily put the code up on github.

I have reduced my code to these 4 files :

Backend.js

var items = [{
		"name": "Name1",
		"info": "Blabla",
		"pictures": [
			{
				"file": "Assets/ped0.jpg",
				"info": "blabla diag"
			}],
		"scenario":[
			{
				"id" : "1",
				"question": "During ...1",
				"question_picture": "img11.jpg",
				"answer1_picture": "img12.jpg",
				"answer2_picture": "img13.jpg"	
			},
			{
				"id" : "2",
				"question": "During ...2",
				"question_picture": "img21.jpg",
				"answer1_picture": "img22.jpg",
				"answer2_picture": "img23.jpg"	
			}
			]
}];

function clone(obj) {
	return JSON.parse(JSON.stringify(obj));
}

function getItems() {
	return clone(items);
}

function getItem(name) {
	var ret = items.find(function(item) {
		return item.name == name;
	});
	return ret ? clone(ret) : null;
}

module.exports = {
	getItems: getItems,
	getItem: getItem
};

MainView.ux

<App>
	<Router ux:Name="router"/>

	<JavaScript>
	var Observable = require("FuseJS/Observable");

	module.exports = {
		currentName: this.Parameter.map(function(param) {
			return param.item;
		}),
		currentId: this.Parameter.map(function(param) {
			return param.itemId;
		})
	};
	</JavaScript>

	<ClientPanel>
		<Navigator ux:Name="navigator" DefaultPath="home">
			<PageOne ux:Template="home" CurrentName="Name1" router="router" />
			<PageTwo ux:Template="page2" CurrentName="{currentName}" CurrentId="{currentId}" router="router"/>
		</Navigator>
	</ClientPanel>
</App>

pageOne.ux

<Page ux:Class="PageOne">
	<string ux:Property="CurrentName" />
	<Router ux:Dependency="router"/>
	
	<JavaScript>
		var Observable = require("FuseJS/Observable");
		var Backend = require("Backend.js");

		function start(item) {
			var id = "1";
			console.log("Start Param1 item " + item.data.name);
			console.log("Start Param2 id " + id);
			router.push("page2", { item: item.name, itemId: id });
		}

		module.exports = {
			item: this.CurrentName.map(function(name) {
			var item = Backend.getItem(name);
			if (item) {
				item.mainPicture = item.pictures[0];
			}
			return item;
			}),
			start: start
		};
	</JavaScript>

	<Panel ux:Class="area.Button" Margin="10" Padding="10" >
		<string ux:Property="Text" />
		<Text Color="Black" Value="{ReadProperty Text}" TextAlignment="Center" Alignment="Center" />
	</Panel>

	<Panel>
		<With Data="{item}">
			<Panel>
				<area.Button Text="Start" Alignment="Bottom" Margin="20" Padding="10" Clicked="{start}" HitTestMode="LocalBoundsAndChildren" />
				<DockPanel Height="250" Dock="Top">
					<Panel Layer="Background">
						<Image File="{mainPicture.file}" StretchMode="UniformToFill" />
					</Panel>
					<Text Color="Black" Value="{name}" FontSize="40" Alignment="HorizontalCenter" Dock="Bottom">
					</Text>
				</DockPanel>
			</Panel>
		</With>
	</Panel>
</Page>

pageTwo.ux

<Page ux:Class="PageTwo">

	<Image Layer="Background" File="Assets/background.png" StretchMode="Fill" Opacity=".7"/>

	<Router ux:Dependency="router"/>
 	<string ux:Property="CurrentName" />
	<string ux:Property="CurrentId" />
	
	<JavaScript>
		var Observable = require('FuseJS/Observable');
		var Backend = require("Backend.js");

		var itemName = this.CurrentName.map(function(param){
		console.log("PARAM1 param " + param);
		console.log("PARAM1 param.value " + param.value);
		console.log("PARAM1 param.item " + param.item);
		return param;
		});


		var itemId = this.CurrentId.map(function(param){
		console.log("PARAM2 param " + param);
		console.log("PARAM2 param.value " + param.value);
		console.log("PARAM2 param.itemId " + param.itemId);
		return param;
		});

		module.exports = {
		itemName: itemName,
		itemId: itemId
		};
	</JavaScript>

	<Panel>
		
	</Panel>

</Page>

the Viewport gives :

Build completed in 9,82 seconds
[Viewport]: Start Param1 item Name1
[Viewport]: Start Param2 id 1
[Viewport]: PARAM1 param 
[Viewport]: PARAM1 param.value undefined
[Viewport]: PARAM1 param.item undefined
[Viewport]: PARAM2 param 
[Viewport]: PARAM2 param.value undefined
[Viewport]: PARAM2 param.itemId undefined

What I would like to have is :

[Viewport]: Start Param1 item Name1
[Viewport]: Start Param2 id 1
[Viewport]: PARAM1 Name1
[Viewport]: PARAM2 1

In the process of reducing the code, I lost the ability to retrieve even the first parameter.
I tried several combinations of param.value param or param.itemName but did not succeed.
I hope with these codes, is my issue explicit enough?
Thank you in advance

Well you’re still mixing up UX properties and router arguments. It’s all far more simple than you make it.

First, your MainView may not contain any this.Parameter mapping in its JavaScript data context, because I don’t see you pushing the router to the root of your app with any parameters. This effectively ruins your reproduction right at the beginning - there is no this.Parameter there. Whatever you expect to happen next, simply won’t.

Second, in your PageOne class you have this line:

router.push("page2", { item: item.name, itemId: id });

But in the JavaScript of your PageTwo, you do not have any reactive mappings on this.Parameter where you would react on receiving that object you pass. All you have there is reactive mapping on the class properties, which were compromised already at the beginning, as I explained above.

Here’s a complete, minimal reproduction that works:

<App>
	<Router ux:Name="router"/>
	<ClientPanel>
		<Navigator DefaultPath="home">
			<PageOne ux:Template="home" CurrentName="Name1" router="router" />
			<PageTwo ux:Template="page2" router="router" />
		</Navigator>
	</ClientPanel>

	<Page ux:Class="PageOne">
		<string ux:Property="CurrentName" />
		<Router ux:Dependency="router"/>
		
		<JavaScript>
			var Observable = require("FuseJS/Observable");
			var itemName = this.CurrentName.map(function(name) {
				return "The name is: " + name;
			});

			function start(item) {
				var id = "1";
				console.log("Start itemName: " + itemName.value);
				router.push("page2", { name: itemName.value });
			}

			module.exports = {
				itemName: itemName,
				start: start
			};
		</JavaScript>

		<Panel ux:Class="area.Button" Margin="10" Padding="10" >
			<string ux:Property="Text" />
			<Text Color="Black" Value="{ReadProperty Text}" TextAlignment="Center" Alignment="Center" />
		</Panel>

		<Panel>
			<Panel>
				<area.Button Text="Start" Alignment="Bottom" Margin="20" Padding="10" Clicked="{start}" HitTestMode="LocalBoundsAndChildren" />
				<DockPanel Height="250" Dock="Top">
					<Text Color="Black" Value="{itemName}" FontSize="40" Alignment="HorizontalCenter" Dock="Bottom">
					</Text>
				</DockPanel>
			</Panel>
		</Panel>
	</Page>

	<Page ux:Class="PageTwo">

		<Router ux:Dependency="router"/>
		
		<JavaScript>
			var Observable = require('FuseJS/Observable');
			var itemName = this.Parameter.map(function(x) {
				console.log("PageTwo received param: " + JSON.stringify(x));
				return x.name;
			});
			module.exports = {
				itemName: itemName
			};
		</JavaScript>

		<Panel>
			<Text Alignment="Center" Value="{itemName}" />
		</Panel>

	</Page>
</App>

and spits this out in the log:

[Viewport]: Start itemName: The name is: Name1
[Viewport]: PageTwo received param: {"name":"The name is: Name1"}

Taking what you gave me,
I added in pageOne class, a second element :

router.push("page2", { name: itemName.value, id : "1" });

In pageTwo I have now :

	var itemName = this.Parameter.map(function(param){
		console.log("PARAM1 param " + JSON.stringify(param));
		return param.name;
		});

		var itemId = this.Parameter.map(function(param){
		console.log("PARAM1 param " + JSON.stringify(param));
		return param.id;
		});

		module.exports = {
		itemName: itemName,
		itemId: itemId

		};

In the Viewport I have now:

[Viewport]: PARAM1 param {"id":"1","name":"The name is: Name1"}

So it indeed worked in the reduce version. I’ll try then in my application.
In the meantime thank you for this help.