Send unencoded query parameters in Ember - javascript

I'm working with an API that only accepts unencoded query parameters. I notice that when I make a query in Ember like so:
this.store.query('listing', {filter: params});
The uri is encoded when it hits the api:
/v1/listing?filter%5Bcategory%5D=123
What I need is for the query parameters to get to my API unencoded, eg:
/v1/listing?filter[category]=123
Can anybody give me a steer on what is the right way to do this in Ember?

So the solution I ended up implementing is not great but it does the trick until I find a better way.
Ember uses Ajax to form the request, so what I did was override 'query' in my JSONAPIAdapter to pass through a custom set of options. My query now looks like this:
query(store, type, query) {
let url = this.buildURL(type.modelName, null, null, 'query', query);
if (this.sortQueryParams) {
query = this.sortQueryParams(query);
}
query = decodeURI(Ember.$.param(query));
let options = {
"processData": false,
"data": query
};
return this.ajax(url, 'GET', options);
},
The key was to stop ajax's automatic processing of the data object, and decode the result of jquery's 'param()' helper function, which is used to convert the query param object into a serialized string.
The result is a decoded query param string like so:
/v1/listing?filter[category]=123

Related

passing non-url encoded parameters to an ajax call in node.js

I am trying to pass parameters from my website to a couchdb server through a node.js server.
I absolutely need to pass {} in a url. Not a string, not an empty object, the actual {} characters. It is used to define the end_key parameter in couchdb views.
At the moment, my call goes like this :
let url = "/trades";
let ajax_options = {
data:{
design_name:'bla',
view_name:'blabla',
params_view:{
group_level:2,
start_key:["1",0],
end_key:["1",{}]
}
}
};
$.ajax(url,ajax_options).then((res) => { ... });
when it passes through NodeJs and the nano library with
db.view(req.query.design_name, req.query.view_name, req.query.params_view)
the end_key object in params_view becomes ["1"] instead of ["1",{}] which I would like to see.
I have verified that with the correct value for end_key, the view gives me the expected result.
How to prevent that behavior from occurring ?

Query string with fetch javascript

I'm working on a project and i want to define url object that will be passed to fetch ex.
https://t1.testing.com/test/api/v1/blog?pagingindex=0&pagingresults=10
const url_object = {
url: `https://t1.testing.com/test/api/v1/blog`,
url_params: {
method: "POST",
pagingindex: 0,
pagingresults: 10
}
};
and when i call fetch(url_object.url, url_object.url_params) i get an error. How can i incorporate this into fetch? So i need to allow user to define method and query string that will be passed. Thanks in advance!
You can have your cake and eat it too -- easily convert dictionary style objects to query parameters with no fuss:
var url = new URL('https://example.com/');
url.search = new URLSearchParams({blah: 'lalala', rawr: 'arwrar'});
console.log(url.toString()); // https://example.com/?blah=lalala&rawr=arwrar
The object you have labeled url_params is described by the MDN documentation as:
An options object containing any custom settings that you want to apply to the request.
It then goes on to list the properties you can include there.
pagingindex and pagingresults are not among them.
The query string is part of the URL. If you want to put data there, then put it in the URL.
const url_object = {
url: `https://t1.testing.com/test/api/v1/blog?pagingindex=0&pagingresults=10`,
url_params: {
method: "POST"
}
};
You may wish to use the URL object to construct the URL (it will handle escaping for you).

Ember data - One model, two endpoints

In ember data, if you want to fetch the collection of a model, it's convention to use this:
this.store.findAll('order');
or with a filter, this:
this.store.find('order', {shopId: 63});
So you pass the model name, and Ember-data will build the URL for you, which would look something like (depending on your adapter):
GET /api/orders
GET /api/orders?shopId=63
So this does two things
Build the URL to fetch data from the api
Map the collection as JavaScript objects, using the model that you passed as 1st argument
But what if I want to fetch orders from two URLs; /api/orders and /api/new_orders ?
The first one will work as usual: this.store.findAll('order'), but is there a way to override the api path that you fetch from?
Maybe something like this.store.find('order', {path: '/new_orders'})?
So that I can end up with a collection of objects modelled with my order model, but fetched from a different route
You need to have a rest adapter for this store and override the findAll method. The default implementation is as such
findAll: function(store, type, sinceToken) {
var query, url;
if (sinceToken) {
query = { since: sinceToken };
}
url = this.buildURL(type.modelName, null, null, 'findAll');
return this.ajax(url, 'GET', { data: query });
}
buildUrl will return a proper endpoint for your first url. you could then parse this url and modify it to make a second request with the same data, but with to your second endpoint. Than you could merge the responses or use them separately.
Reference: https://github.com/emberjs/data/blob/v1.13.5/packages/ember-data/lib/adapters/rest-adapter.js#L398

Json stringify then parse from URL

I seem to be having an issue in stringify'ing then pasing from a url object
I simply stringify my object and set the location (with angulars $location) like so
currentUrl = {"module1" : {"is" : true} }
$location.search(JSON.stringify(currentUrl));
So this parses to the url just fine, however when I try to grab it from the url i get this back
console.log($location.search());
---
Object {{"module1":{"is":true}}: true}
How do I parse this back into an object so I can use it? If I do
JSON.parse($location.search());
I get a syntax error. I maybe because of how search returns the object? I am a bit confused here, could use some help. Thanks!
So I put it in the url with
$location.search(JSON.stringify(currentUrl));
What are the steps I need to take to get it back into this form :
{"module1" : {"is" : true} }
Edit -
It just appears it's setting the json object as the key in the location like
{ "mystrigifiedobject": true }
Edit2 :
based off the first edit, I was able to solve it (assming it's set in the locations object key) like so :
currentUrl = $location.search();
currentUrl = JSON.parse(Object.keys(currentUrl));
console.log(currentUrl);
This just feels a little weird though, am I doing something wrong here?
$location.search() returns the parsed search items from the url path as an object. This means this kind of url:
?a=b&c=d
will result in this object:
{ a: 'b', c: 'd' }
When you call this function:
currentUrl = {"module1" : {"is" : true} }
$location.search(JSON.stringify(currentUrl));
your path will look like this:
?%7B%22module1%22:%7B%22is%22:true%7D%7D
and the parsed object returned from $location.search will look like this:
{{"module1":{"is":true}}: true}
not that this is an object with one entry and the key is your JSON
So what you need to do in order to get your object back is this:
var parsedObject = $location.search();
var yourObject = JSON.parse(Object.keys(parsedObject)[0]);
see this jsfiddle: http://jsfiddle.net/HB7LU/11633/
But please note: you should encode your string when putting it in a url:
$location.search(encodeURIComponent(JSON.stringify(currentUrl)));
$routeParams provides access to both routing template values and query string values (as a string).
function ctrl($routeParams) {
var yourValueAsString = $routeParams.yourKey;
}
function ctrl2($location) {
$location.search('yourKey', JSON.stringify(...));
}
A better alternative would be to switch to using the UI Router which deals with this better.

How to only use a certain dict from a get request with Backbone?

I have exposed to Backbone an API that returns user profiles with this structure:
{id: 1, following: {...}}. I only want to use the dictionary inside of the "following" attribute. How would I do that? Right now, I have a model with a URL to the API. I have a collection that uses this model. I do a fetch() on the collection, but I only want to use the dictionary inside of "following".
You should use parse to extract what you want from the the response:
parse model.parse(response)
parse is called whenever a model's data is returned by the server, in fetch, and save. The function is passed the raw response object, and should return the attributes hash to be set on the model.
So you'd want something like this in your model:
parse: function(response) {
return response.following;
}

Categories

Resources