How to parse url with Meteor - meteor

I'm using Meteor with another CMS, and am creating a url with the variables I need to run Meteor (ex. http://site.com?a=flash&b=hash). How to I make those variables usable, and get Meteor to ignore it as a location? When I load the url like that, my app doesn't load correctly, presumably because it thinks I'm requesting a different location.

Using iron router, if there is a query string or hash fragment in the url, you can access those using the query and hash properties of the this.params object.
// given the url: "/post/5?q=s#hashFrag"
Router.route('/post/:_id', function () {
var id = this.params._id;
var query = this.params.query;
// query.q -> "s"
var hash = this.params.hash; // "hashFrag"
});

Use of the querystring in Meteor should have no effect unless you're using eg. Meteor Router to invoke different methods depending on the current URL.
If you want to parse the querystring, just parse it by hand with eg. (in coffeescript)
querystring: ->
qs = {}
for pair in window.location.search.replace("?", "").split "&"
[k, v] = pair.split("=")
qs[k] = v
qs
Which will return an object like:
{ "a": "flash", "b": "hash" }

Related

How to traverse object with dynamic keys in Paw?

Let's say we have the following JSON response:
{
"abcd1234": {
"foo": "bar"
}
}
How would "bar" be accessed in a response parsed body value? In the response, "abcd1234" could be anything. But we want the first key in the object (in JavaScript this would be Object.keys(res)[0]).
Paw makes it easy to parse JSON (and XML) responses and access subfields via their key-path.
This documentation article may help: https://paw.cloud/docs/advanced/reuse-values-from-previous-responses
Insert the Response Parsed Body dynamic value
Set the input request and extract the needed value
In your example, the key path will be:
abcd1234.foo
Though, it seems like you need to access the path without knowing the key before hand. If so, one way would be to use a JavaScript snippet to be able to achieve the behavior you want.
On any field, you may right-click and pick Extensions > JS Script.
Here's a snippet that may fit your needs:
function evaluate(context){
var request = context.getCurrentRequest();
var exchange = request.getLastExchange();
var body = JSON.parse(exchange.responseBody);
var key = Object.keys(body)[0];
var value = body[key].foo;
return value;
};

How to parse a collection's sub-object to find a unique result from many possibilities?

In my user's schema, I have a TokAuth Array with token sub-objects (like multiple mails addresses).
So in a method, when I search the tokens in the current user :
var id = Meteor.userId();
var usercurrent = Meteor.users.findOne({_id: id}, {fields: {"TokAuth": 1}});
var userToken = usercurrent.TokAuth.token;
I got in console.log(userToken)
[ 'fyAyXkXYrQdAlNpjuQfJ8RLU2TpfVGLnptlBs-m1h7xk',
I20170224-20:36:23.202(1)? 'YTwtUbhNTgiEfzFbJq7mESnOoOHeLYxWlqEeJJIG_GiV',
I20170224-20:36:23.206(1)? 'ViA4ydDITJtHDi2c_sArkNtpRYTjFqGL1ju2v00_-rFJ',
I20170224-20:36:23.206(1)? '51ImZcxRADLJr-FPCUL7EFGnTZYjHSZk3XxdqtBV2_fd',
I20170224-20:36:23.207(1)? 'S5aEvqjJ5zTUJqLFCPY1aZ1ZhsQppZTJtYKULM9aS2B3',
I20170224-20:36:23.207(1)? 'mhBs3oxHf2SxZfu2vCZhtiyPfg25fKMY8bKMZD8fx6IG',
I20170224-20:36:23.207(1)? '-rv0FiP-lxoqe8INyCJASV6rZpbgy3euEqB9sO9HsZSV',
I20170224-20:36:23.207(1)? 'zacr6_VBjHTsArov1LmQyZFLwI40fx4J7sygpLosTrli' ]
Beside, I've got a var who is equal to the last token in the userToken sub-object (that's of course expected : not to be the last one, but to be in the sub-object).
console.log (editAuth);
zacr6_VBjHTsArov1LmQyZFLwI40fx4J7sygpLosTrli
So how can I parse userToken to find a match with editAuth? If userToken was just a String, it will be simple but here...
Thanks
Is there a reason you are storing all the tokens as an array as opposed to just updating a single string each time?
That aside, you can check if an array contains a value by using the handy underscore function _.contains
Example:
_.contains( userToken, editAuth ); //returns true or false
In this case, you are simply trying to search for a string within an array of strings. #Sean already provided one solution.
If you are using the meteor ecmascript package then you can just simply use the native Array.includes method.
userToken.includes(editAuth);
On a side note, after using ECMAScript 2015+ for some time now, I find that I can use the native API for almost everything that I used to use underscore or lodash for. Check it out!

How do I handle values that are dependent on the result of a helper?

So I have an Angular controller with a meteor helper method, as below.
function localeCtrl($scope, $reactive, $stateParams{
$reactive(this).attach($scope);
var self = this;
self.helpers({
locale: function(){ return Locales.findOne($stateParams.id)},
staff: function(){
// Load data from second collection based on current Locale.
// But how?
},
address: function(){
// Take self.location.address and massage it to provide
// google maps link. How?
}
tags: function(){
// Collect all unique instances of a given tag by
// iterating over the available locales.
// E. G. If 10 locales have the 'restaurant' tag, and 5
// more have the 'library' tag, I want an array of
// ['restaurant', 'library'] -- easy enough to do
// by iterating over the locales, but how do I do that
// reactively?
}
});
}
Unfortunately, I need to set additional properties based on the data fetched by locale(). I can't set them up when I initialize the controller because the value in locale() changes as data is fetched from the server. But I need access to the data in locale to, for example, create the google maps address, or fetch associated records. (They aren't imbedded in the locale document for reasons that I'm sure made sense at the time).
Edit:
Additionally, I'm using ground DB to store a local copy of the data for offline access, which makes life even more complicated.
Probably you best bet is to publish your collection using publishComposite which is implemented using the reywood:publish-composite package.
Add the package:
meteor add reywood:publish-composite
Now where you publish the Locales collection you would do something like this:
Meteor.publishComposite('locales', function() {
return {
find() {
//Put whatever you need in the query for locales
const query = {
_userId: this.userId
};
return Locales.find(query);
},
children: [{
find(locale) {
return Staff.find({ localeId: locale._id });
}
}]
};
});
Then in your controller before the helper you add this:
this.subscribe('locales');
Now you should be able to simply call the code like this:
this.helpers({
locale(){
return Locales.findOne(this.$stateParams.id);
}
});
And access it in the template like this:
locale.staff
Give that a try and let me know!

meteor restivus how to read multiple queryParams

I am building an API with Restivus in Meteor.
In a custom route I would like to have multiple values as queryParams like this (e.g. value1 and value2):
...domain/api/update?key=1234&value1=10
How do I get them in endpoint function?
When I try this I get undefined:
var query = this.queryParams.key // result: 1234
var value1 = this.queryParams.value1 // result: undefined
Update
This is my new fresh code with the same result.
Use a standard Meteor project. Meteor version 1.0.3.2
// Create collection
Posts = new Mongo.Collection("posts");
if (Meteor.isServer) {
Meteor.startup(function () {
// RESTIVUS
// Global configuration
Restivus.configure({
useAuth: false,
prettyJson: true
});
// Given the url: "/posts?key=1234&value1=10"
Restivus.addRoute('posts', {
get: function () {
var key = this.queryParams.key;
var value1 = this.queryParams.value1;
console.log("key: " + key); // result: 1234
console.log("value1: " + value1); // result: undefined
}
});
});
}
This is the solution to the problem. Taken from here:
https://github.com/kahmali/meteor-restivus/issues/16
You're using curl to test, right? Well apparently (and don't feel bad for not knowing this, because neither did I), the & symbol means that the previous command will be run in the background, so the query params were just being truncated once the curl command reached the & for the second query param. All you have to do is wrap the URL in quotes, and voila! Try this command instead:
curl "http://testivus.meteor.com/api/posts?key=1234&value1=10"
That should work. So if you had just punched that URL into a browser or used a mored advanced REST client, you would have seen the extra query param defined. I got the answer from this StackOverflow question.

How to use URL parameters using Meteorjs

How can I use URL parameters with meteor.
The URL could look like this: http://my-meteor.example.com:3000?task_name=abcd1234
I want to use the 'task_name' (abcd1234) in the mongodb query in the meteor app.
eg.
Template.task_app.tasks = function () {
return Tasks.find({task_name: task_name});
};
Thanks.
You are probably going to want to use a router to take care of paths and rendering certain templates for different paths. The iron-router package is the best one available for that. If you aren't using it already I would highly recommend it.
Once you are using iron-router, getting the query strings and url parameters is made very simple. You can see the section of the documentation here: https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#route-parameters
For the example you gave the route would look something like this:
Router.map(function () {
this.route('home', {
path: '/',
template: 'task_app'
data: function () {
// the data function is an example where this.params is available
// we can access params using this.params
// see the below paths that would match this route
var params = this.params;
// we can access query string params using this.params.query
var queryStringParams = this.params.query;
// query params are added to the 'query' object on this.params.
// given a browser path of: '/?task_name=abcd1234
// this.params.query.task_name => 'abcd1234'
return Tasks.findOne({task_name: this.params.query.task_name});
}
});
});
This would create a route which would render the 'task_app' template with a data context of the first task which matches the task name.
You can also access the url parameters and other route information from template helpers or other functions using Router.current() to get the current route. So for example in a helper you might use Router.current().params.query.task_name to get the current task name. Router.current() is a reactive elements so if it is used within the reactive computation the computation will re-run when any changes are made to the route.

Resources