How do I access URL parameters in Meteor helper functions? - javascript

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.

Related

Vue Router dynamic segment with params

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...

How to pass params to child window through ui-router

I have a requirement where I have a parent window with a button. Clicking on the button performs some logic, computes some values and opens a child window with those params. I'm trying to find a good way to do this. My current implementation is as follows.
Inside my ng-click method I have
let location = this.$state.href('moveout', { entityUuid: this.entityUuid, count: count, params: params, options: options);
let unDockedWindow = this.$window.open(location, '', 'scrollbars=no,fullscreen=yes,toolbar=no');
This successfully opens a child window with url that looks like the below
#/moveout?entityUuid=8eb6c75e-5a06-333c-a4cf-a97d90995722&count=something&params=something&options=something
I'm able to access the data in the destination like so
$state.params.entityUuid
My problem however is that, some of these attributes can be complex, like params and options. And I don't necessary want to have a url that has so many params and looks really ugly.
I'm trying to see if there is a way to open a child window with a number of params with ui-router without passing them as query string params.
I don't think I want to use ui-sref since some of the values that need to be passed need to be computed based on some logic. Hence doing it inside ng-click.
Any help, greatly appreciated.

How to get url parameters in Backbone?

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.

how to pass "question mark" in url javascript

In Angularjs app, i have a url like http://url.com/my_app/#/store/items.
Now i want to append query string for example, http://url.com/my_app/#/store/items?page=2. but in url, javascript encodes the "?" to "%3F" which i don't want. It should remain "?" only in the url as angularjs $location.search() returns nothing for "%3F".
How it can be done ?
There is not enough details in your question so I will assume that you are using AngularJS routing - or at least the $location service - in non-HTML5 mode. If so, the part after the # character represents your URL from the single-page-application point of view (more about AngularJS here).
If the above assumptions are correct it means that you shouldn't try to add or manipulate the question mark "by hand". Instead you should change the search part of the $location to manipulate query string (part after ?) and the question mark will be added / removed to the final URL as needed.
In your case you could write:
$location.path('/store/items').search('page', 2)
This is assuming that you are manipulating URLs from JavaScript, as stated in your question.
If you are using the $location service then use $location.url('/store/items?page=2') instead. This has been a setter method from at least 1.0.7 and works a treat in my 1.1.5 app.
you can create a parameter object like:
var param = {
page: 2
}
$location.url("/store/items").search(param)
If you're using the ui-router which is highly recommended, you could use $state.go(to, params, options) as described here.
As prerequisite you need to define your state properly, that means every possible query parameter must be made known to the ui-router. See the following example (page and otherParam):
$stateProvider.
state('storeItems', {
url: '/store/items?page&otherParam',
templateUrl: '/modules/store/views/item.client.view.html'
});
And then you can just switch locations for instance from a controller by calling
$scope.gotoItemsPage = function(page) {
$state.go('storeItems', {
page: page,
otherParam: 'Just a show off'
});
};
No fiddling with the encoding needed and highly readable!
You can use decodeURIComponent.
For example:
decodeURIComponent('http://url.com/my_app/#/store/items%3Fpage=2');
// will give you `http://url.com/my_app/#/store/items?page=2`

Routing for flexible JavaScript Single-Page-App?

I'm building a single page web app (because I want flexibility and speed when moving across pages/states) but I'm struggling with routing / urls ...
In the traditional paradigm I would have urls such as:
example.com/tools/population-tool/#currentYear=1950
example.com/tools/income-tool/#country=usa
example.com/nice-story/
example.com/nice-chapter/nice-story/
Now I'd like to replace this with a Router (for example using Backbone) that loads templates and controllers for the corresponding routes.
I'm thinking about having a pages object that stores the necessary page information:
pages : {
tools : {
template : "#tools",
breadcrumb : ["Home","Tools"]
}
nice-story : {
template : "#nice-story",
breadcrumb : ["Home","Stories","Nice Story"]
}
}
With a router, I'd now like load the right content and page state, given a url like:
example.com/#!/tools/population-tool/?currentYear=1950
or like this if not using Hashbang:
example.com/tools/population-tool/?currentYear=1950
How would you organize this routing so that the url scheme makes sense while still being flexible and allow for redirects and new query string paramaters?
This is not a complete answer to your question, but a few tips on Backbone...
You may want to define a method like loadPage() on your router which can empty and replace your main page container with a view that corresponds to each "page" in your app. Each route action can call that to load up the right view.
If you will be using pseudo query strings, make sure to add a matcher for them explicitly in your Backbone routes. For example:
'/tools/population-tool/?*params'
That will call your route action with the entire params string as the first parameter. You'll need to parse that...

Categories