I am trying to create a route that can handle both dynamic segments and accept router-props (params). Something like this:
{ path: '/peer:body?', name: 'peer', component: () => import('pages/peer.vue'), props: true }
And eventually push a route like this:
this.$router.push({ path: '/peer/' + row.body, name: 'peer', params: { row: row } })
Unluckily, I am only able to use dynamic segments using pathas route property or params using nameas route property, but never simultaneously.
First, as you already mentioned, when constructing "location descriptor object" for $router.push (or to prop of <router-link>), you can use path or name, not both at the same time (doesn't make sense to do so)
Second, you can pass params only when you use name (as described here - paragraph between first two code samples). To overcome this you can use query instead of params or build whole path including the params into the URL string.
And that brings me to the most important part of my answer. It seems as you are trying to pass a complex object as a route param (and into the target component props). While this is technically possible, it's not a good way of doing things. You have no place in your path definition where to put content of such parameter - it will work with push or clicking <router-link> where parameter is provided as an object, but when user accesses that URL directly (by copying and pasting URL for example), the page will be broken because prop parameter will be missing (as it cannot be extracted directly from the URL).
So my advise is to avoid that. Put your data into something like Vuex and instead of passing whole object by router, pass only some kind of identifier that can be included in the URL, extracted by Router and passed as a prop into target component. Then your target component should grab the Id and use it to query Vuex to get the data it needs...
Related
I want to use ejs layouts to only some of the files (not the whole project). But using express-ejs-layouts it uses layout to all files. Here is the core part of the code.
app.get("/page1",(req,res)=>{
res.render("p1");
});
app.get("/page2",(req,res)=>{
res.render("p2");
});
app.get("/page3",(req,res)=>{
// Don't add Layout file in this page
res.render("p3",{
layout:null
});
});
I found in stackoverflow that you can use multiple layouts by passing an object having a key layout and its value as name of layout file { layout : "layoutNumberOne" }. But setting its value to undefined or null doesn't work. And the solution I want is not to create an empty layout file and passing the name of that file in the object to the render() function which will work, because if that is the case I will have to specify the { layout : "emptyLayout" } in all the pages which I have a lot. I am looking for an answer that can add a layout to a specific route, so that all requests in the route will have this layout file and will not affect other paths. How can I do that ?
you could write a helper function like this:
function demo(route, view, data={}){
app.get(route, (req, res) => {
let options;
if(route === "/page3"){
options = {
layout: "blank-layout"
};
};
const locals = {
...data,
...options
};
res.render(view, locals)
});
}
and call it whenever you want to render a page:
demo("/page3", "p3", {anything: "whatever you want"})
This function takes in a route, view file, and an optional data object in the likely event that you want to pass in some dynamic data to use inside your template.
It sets your desired route, then initialises a variable called "options" to later be passed into the "locals" object below once the if statement has given it a value.
The function then compares the value of your "route" parameter to the route you want to assign some unique options to (in this case "/page3"), should the result be true it'll set the "options" variable to be an object with a property called layout and a value of "blank-layout". The value pertains to the name of the layout file you would like to use so feel free to change that value to suit your needs.
Finally this "options" object is merged with the "data" object you may have passed in earlier (if you didn't pass one in it'll just use an empty object); the result of merging the two objects is stored in the "locals" variable and now contains every property your data object and options object have. This variable is then passed into the render function along with the view file.
note that you can use multiple if statements to set options for other routes
I'm wondering if I can use the parameter from path in vue-router's meta data field. For instance, here I am using the parameter entity_id in the path.. but, I want to also use that parameter as a property/parameter in the meta property so that I can use it more easily:
{
path : ':entity_id',
name : 'DashboardEntity',
component: DashboardEntity,
meta : {
label: 'Example',
iwantthistobetheid: ':entity_id'
},
},
The reason is that I have a breadcrumb file that lists out the routes/children/etc. and I want to display the ID in the breadcrumb.
I can do that in the above example by using this.$route.params.entity_id in my breadcrumb view.. but then I have to name every parameter in my routes something generic like id to have it display every time.
Any idea of how this might be possible or a solution that doesn't require me to either rename all my router parameters or have a huge if/else to check each routers params to display in my breadcrumb view?
You should be able to do this:
this.$route.params[this.$route.meta.iwantthistobetheid]
that would be the equivalent of
this.$route.params.entity_id
or if iwantthistobetheid = 'object_id'
this.$route.params.object_id
Example
http://localhost:4200/login?aUasas129198
resolves to
http://localhost:4200/login
What should I do if I want the value after '?'
I tried doing
{ path: 'login/:id', component: LoginComponent },
But it did not work
I also tried
console.log(this.route.snapshot.queryParams);
console.log(this.route.snapshot.params);
But they both return empty object. What should I do now please help
If it’s unavoidable that Angular redirects you immediately and loses the query parameters, you could subscribe to router events and on each NavigationStart for login route get a hold of route’s queryParamMap or snapshot.paramMap before they’re lost in redirection, then you can e.g. pass it to a service and do whatever you wanted to do with it.
Or, as another alternative, you could look into configuring your router with queryParamsHandling: 'preserve', in which case it should pass the query params to the next route (see the section in Angular docs linked below for more on this).
I worked with a project that made use of query params in Angular 5, IIRC I don’t think it would redirect on its own so I’d recommend to look elsewhere in your project but I may be wrong.
See also
Routing & Navigation → Query parameters and fragments in Angular docs
Angular Route Start and Route End Events on StackOverflow
Actually, You are not passing the value in any key:
http://localhost:4200/login?aUasas129198
The proper way should be:
http://localhost:4200/login?anykey=aUasas129198
// get it as
// this._ActivatedRoute.queryParams.subscribe()
If you are using the URI as you shown in your question as:
{ path: 'login/:id', component: LoginComponent }
Then you should pass the value to id as:
http://localhost:4200/login/aUasas129198
// remember the '/' after the login that you didn't use.
// get it as
// this._ActivatedRoute.snapshot.params.id
I'm using Backbone with Marionette.
I have a link <a> tag where I'm passing few parameters, how can I extract those values in other pages using Backbone?
View Details
Address Bar url:
http://localhost.com:8080/help/?name=matth&age=25&email=matt#gmail.com 44
Using Php, this is straightforward:
$Url = $_GET['state']."#".$_GET['city'];
How can I achieve it within my Backbone app?
If the route is defined with something like this:
'help/:name&:age&:email' : 'help'
Then you can access those params in the help function just by defining them in the signature of the method (within the backbone router),
help: function(name, age, email) {
// do whatever you want with the params
}
In your case, this will give you params like this:
name="XXX" age="XXX"
So the proper routing would be
'help/?(name=:name)(&age=:age)(&email=:email)' : 'help'
Where parentheses make a part optional.
Backbone docs
Routes can contain parameter parts, :param
Note that the order is important and the following url wouldn't trigger the route callback. Notice the email and age params placement.
help/?name=test&email=test%40example.com&age=6
In order to trigger a route regardless of the number of params and their ordering, take a look at how to parse the query string in the route function, but that won't always work.
For some of the pages in my application, I would like to enable a printable mode, wherein some elements of the page are hidden when the URL parameters include ?print=true. Currently I have attempted a workaround that involves sending the URL parameters as a data context thru iron-router.
this.route('permitsList', {
path: '/permits/',
path: '/',
waitOn: function(){
return Meteor.subscribe('openPermits');
},
data: function(){
return this.params;
}
});
Accompanied by a global handlebars helper which is used to show and hide elements appropriately.
In this case, when the URL contains ?print=true, it's trivial to show and hide the appropriate elements. However, this solution has two major issues. The first, is the fact that some of the pages for which I wish to implement this printable view already have a data context. Overwriting the data context is not viable, and embedding both data contexts into a larger object is rather disgusting. The second issue is that I wish for the printable view to apply not only inside the template itself, but also in the surrounding layout template in which the page is rendered, so that extraneous headers and so on are removed.
Is there any reasonable way to access URL parameters inside of a Spacebars helper without specifying the parameters in the data context through Iron Router?
To sum up as answer:
Query parameters can accessed even without meteor
if ( window.location.search.indexOf( '?print=true' ) > -1 ) { ... }
window.location returns the current URL, window.location.search only the query parameters as string.