Nextjs <Link> not passing query params when using `as` [duplicate] - next.js

I have a Link where I want to pass certain params in the URL but I don't want the browser to display the params.
I'm using Link's as for this:
<Link href={`/link?foo=bar`} as ={`/link`}>
<a>Link</a>
</Link>
But when I click this link and I try to access the params via router, I can't access foo=bar:
const router = useRouter()
console.log(router.query)
Returns
{
slug: ["link"],
}
And not
{
slug: ["link"],
foo: "bar",
}
So how can I access the URL params in href when using as for Link?

TL;DR You can't use as like that.
This is an incorrect usage of href and as. It would be cool if we could hide state from the end users to keep our URLs nice, clean, and compact, but obviously if you do that, you'll actually lose the state when copy/pasting the URL. That's why you can't hide query parameters in anyway (except for excluding them).
Here's the docs on href and as (dynamic routes, has little to do with hiding query params):
https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes
And to further bring up my point, imagine if we could hide state, and we redirect to this URL:
https://example.com/stateful/
Presumably there would be some behind-the-scenes browser action that persists the state.
Now we copy/paste the URL:
https://example.com/stateful/
Oops! We don't have the state anymore because the browser has no previous state to keep track of! That's why you use query parameters, because they keep the state in the URL itself.

Related

Accessing URL params in "href" when using "as" for Next Link?

I have a Link where I want to pass certain params in the URL but I don't want the browser to display the params.
I'm using Link's as for this:
<Link href={`/link?foo=bar`} as ={`/link`}>
<a>Link</a>
</Link>
But when I click this link and I try to access the params via router, I can't access foo=bar:
const router = useRouter()
console.log(router.query)
Returns
{
slug: ["link"],
}
And not
{
slug: ["link"],
foo: "bar",
}
So how can I access the URL params in href when using as for Link?
TL;DR You can't use as like that.
This is an incorrect usage of href and as. It would be cool if we could hide state from the end users to keep our URLs nice, clean, and compact, but obviously if you do that, you'll actually lose the state when copy/pasting the URL. That's why you can't hide query parameters in anyway (except for excluding them).
Here's the docs on href and as (dynamic routes, has little to do with hiding query params):
https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes
And to further bring up my point, imagine if we could hide state, and we redirect to this URL:
https://example.com/stateful/
Presumably there would be some behind-the-scenes browser action that persists the state.
Now we copy/paste the URL:
https://example.com/stateful/
Oops! We don't have the state anymore because the browser has no previous state to keep track of! That's why you use query parameters, because they keep the state in the URL itself.

tabs value change in url (edit url hash value), onRendered does not trigger in meteor Blaze FlowRouter

I want to get the URL # value after editing the URL link and press keyboard Enter button.
(Environment:- Meteor, Blaze, FowRouter).
from
http://localhost:3000/api/information#feedback
to
http://localhost:3000/api/information#reviews
I'm certain you can get the hash from flow router for the url. Although Flow-Router might not give it straight to you, you could parse the url for it.
You could access it in Meteor.startup() for instance.
Meteor.startup(function () {
console.log(FlowRouter.current());
});

How can I change Angular2 route query parameters without navigating to the route?

I have an angular2 page shows a list of items. I restrict the list initially by using the route parameters so my URL is something like:
http://localhost:54675/#/listing?filter={"Country":[6, 7]}
This will show items in the country with an ID of 6 or 7.
Then the users adds a third country (let's say 8) and I make a service call which updates the list. Since the list items are bound to an observable the list then updates on the screen.
This is exactly the behavior I want. But if the user bookmarks this page they only get the original route parameters and not the filtered results.
To fix this, I use:
this._router.navigate(['listing', { filter: newfilter }]);
This reloads the page with this route:
http://localhost:54675/#/listing?filter={"Country":[6,7,8]}
This keeps everything in sync and bookmarks work. However, there is a full page refresh. Other items load again - not just the filtered results. I also like the visual results better when it's just a single service call.
I need a way to change the route parameters without reloading the page.
You can use the Router only to create the URL and then use the Location to change the URL without navigating.
Something like this:
import { Location } from '#angular/common';
import { Router } from '#angular/router';
// Generate the URL:
let url = this.router.createUrlTree(['listing', { filter: newfilter }]).toString();
// Change the URL without navigate:
this.location.go(url);
For anyone who still didn't find a proper solution, try this:
this._router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {
filter: newfilter
},
queryParamsHandling: 'merge'
});
When navigating to the same route, the site doesn't reload!

Spacebars-generated dynamic links do not trigger Iron Router in Meteor?

I've got this in my routes:
Router.route('/videos/:id', {
name: 'VideoPage',
data: function(){
return Videos.findOne(this.params.id);
}
})
This template shows up at the route above:
Template.VideoPage.helpers({
'videoIds': function(){
var myVideoIds = [
"23456",
"h5e45t",
"f4e4w",
"g6h4h"
];
return myVideoIds;
}
});
HTML:
<template name="VideoPage">
{{videoTitle}}
<p>Click the links below to get to a new video page</p>
{{#each videoIds}}
<a href="/videos/" + {{this}}>
{{/each}}
</template>
When I click on a link, the URL in the browser changes from something like /videos/23456 to something like /videos/f4e4w, but the request never actually goes through Iron Router and the Router.route function. I put a debugger before Router.route and it triggers on initial page load but does NOT trigger when the links are clicked.
I understand that Iron Router's default behavior is NOT to re-render a template the user is currently on, but this is the same template with different url params that are used to change the data in the template, so IMO it should still re-render.
Ok, false alarm. It appears that Router.route DOES fire and updates the data context every time the params._id changes. I was placing the debugger outside of the Route function when I should have been placing it inside of the data context function.
The example that I gave in this answer was also a highy, highly simplified example. It wasn't working in my real-life project due to something else (a complex video iframe generator) that was being refreshed improperly.
But rest assured that going from /videos/f4e4w to /videos/23456 by clicking a link DOES still go through Iron Router and the params does get read and the data does get updated.

How to set querystring or parameters dynamically with iron-router?

I've seen this thread on how to append/modify query parameters without duplicating, but I can't make it work.
I have a page in my Meteor application that lists items and allows filtering. I would like the filtering to be URL-based, so every change to a filter should reflect in the URL.
I use iron-router to then update the subscription accordingly.
For some reason, I can't modify the querystring though. This code doesn't trigger any action if called from a Template.templateName.events(...):
# valuePairs = ["foo=bar", "bar=foo"]
newUrl = Router.current().route.path {}, { query: valuePairs.join('&') }
Router.go newUrl
But if I call Router.go(newUrl) from the commandline, the expected result happens, i.e. the URL updates.
Is there another, preferred method to modify the query?
If not, how can I make above code work?
UPDATE - I just found that after running the event, if I go back in my browser history I can see the correct URL. It looks like something (?) triggers another page load to go back to original page.
Just based on
if I go back in my browser history I can see the correct URL
Do you suppress the actual link event? An <a href='#'> would flip flop you right back.
Template.tempyTheTemplate.events({
'click awesomeButton': function() {
// URL stuff
Router.go(magicURL);
return false; // <-- suppresses the event
}
});

Resources