Router replacing multiple routes

Hi there

How would one go about replacing multiple routes in the route stack in Fuse?

For instance, say the user’s current route stack is StorePage > AddProductPage > ConfirmPage

However, once they confirm I want to erase that previous history and put them on CartPage, with the option to go back to the initial StorePage (so a stack of StorePage > CartPage).

How do I do so without invoking a strange transition?
I could do…

router.goBack();
router.replace('CartPage');

…But then the app would suddenly flash to the StorePage, before transitioning to CartPage.

Is there a way of replacing both the current route and the previous route at the same time? (while maintaining a smooth transition)
Maybe something like…?

router.modify({
    'how': 'Replace',
    'replaceDepth': 2,
    'path': ['CartPage', {}]
});

This kind of flow adjustment is something I seem to need a lot with mobile apps, and I seem to have struggled with it in most frameworks. I dunno if I’m maybe thinking about things wrong, or missing something obvious, but it’s also proving to be hard to do in Fuse.

Any help would be much appreciated, thanks.

RouterModify and its JS counterpart do seem to be exactly what you should be using to achieve what you’re after.

But that’s just about the route stack. You definitely need some more configuration around transitions, so that when you’re navigating in non-linear ways, you wouldn’t get the artefacts you’re mentioning. See Transition docs for details, and make sure to check out the example linked at the bottom of that section.

If these tips don’t help and you’re still stuck, please post a complete, minimal, ready-to-run example that shows the problem and we’ll take it from there.

Hope this helps!

Hi Uldis, here’s an example:

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

	<JavaScript>
		module.exports.onGoto2 = function(){
			router.push('Page2');
		}
		module.exports.onGoto3 = function(){
			router.push('Page3');
		}
		module.exports.onGoto4 = function(){
			router.push('Page4');
		}
		module.exports.onRoute4 = function(){
			//replace the last 2 pages with Page4
			router.goBack();
			router.modify({
				'how': 'Replace',
				'path': ['Page4', {}]
			});
		}
		module.exports.onBack = function(){
			router.goBack();
		}
	</JavaScript>

	<Navigator DefaultPath="Page1">
		<Page ux:Template="Page1" Color="#faa">
			<StackPanel Alignment="Center" ItemSpacing="20">
				<Text Value="Page1" Color="#000" />
				<Button Text="Goto Page2" Color="#fff" Padding="20" Tapped="{onGoto2}" />
				<Button Text="Goto Page4" Color="#fff" Padding="20" Tapped="{onGoto4}" />
			</StackPanel>
		</Page>
		<Page ux:Template="Page2" Color="#afa">
			<StackPanel Alignment="Center" ItemSpacing="20">
				<Text Value="Page2" Color="#000" />
				<Button Text="Goto Page3" Color="#fff" Padding="20" Tapped="{onGoto3}" />
				<Button Text="GoBack" Color="#fff" Padding="20" Tapped="{onBack}" />
			</StackPanel>
		</Page>
		<Page ux:Template="Page3" Color="#aaf">
			<StackPanel Alignment="Center" ItemSpacing="20">
				<Text Value="Page3" Color="#000" />
				<Button Text="Reroute to Page4" Color="#fff" Padding="20" Tapped="{onRoute4}" />
				<Button Text="GoBack" Color="#fff" Padding="20" Tapped="{onBack}" />
			</StackPanel>
		</Page>
		<Page ux:Template="Page4" Color="#faf">
			<StackPanel Alignment="Center" ItemSpacing="20">
				<Text Value="Page4" Color="#000" />
				<Button Text="GoBack" Color="#fff" Padding="20" Tapped="{onBack}" />
			</StackPanel>
		</Page>
	</Navigator>
</App>

When navigating from Page 3 to Page 4, I want to erase Page2 from the history, then replace the current Page3 with Page4, so it transitions smoothly, and route stack becomes Page1 > Page4.

I can currently do this by going back a page, and then replacing the current with Page4, or by using a goto to jump back to Page 1, then push page 4. But both of these involve 2 navigations, so don’t allow me to transition smoothly.

I think the best solution would be to provide something like an erase action:

router.modify({
	'how': 'erase',
	'path': ['Page2']
});
router.modify({
	'how': 'replace',
	'path': ['Page4']
});

I’ve have played with trying to achieve this with custom transitions, but it doesn’t seem possible as the Page3 > Page1 transition plays instantly and snaps to Page1, before the Page1 > Page4 transition plays. I can’t find a way of making 3 persist, so it can smoothly transition to 4.

Thanks again

There is another option to modify called transition. You can specify transition: "Bypass" to avoid any animation for a particular transition. You could perhaps consider using, along with how: "Goto" to recreate the history up to the final page, where a normal transition is used.

In upcoming versions you’ll be able to bind invidiual navigator histories to JavaScript arrays. This will allow you to play directly with the history, which should make such a thing easier.

I guess it’d be possible to introduce history modification functions as well. But hopefully the state driven history should be enough.

Ahh, good idea edA-qa mort-ora-y!

Also having them as manipulatable arrays sounds really useful!

I ended up writing this utility method for anyone else that needs it:

function setNewRoute(route){
	router.getRoute(function(currentRoute){
		currentRoute = currentRoute[currentRoute.length-2];
		for(var i=0;i<route.length-1;i++){
			router.modify({
				'how': i==0?'Goto':'Push',
				'transition': 'Bypass',
				'path': [route[i], {}]
			});
		}
		router.modify({
			'how': 'Push',
			'transition': 'Bypass',
			'path': [currentRoute, {}]
		});
		router.modify({
			'how': 'Replace',
			'path': [route[route.length-1], {}]
		});
	});
}

It allows you to completely replace the current route stack with a new one, and smoothly transition into it. Used like:

setNewRoute(['Page1','Page4']);

Cheers!

1 Like