construct array back together - javascript

My script reads EventSource, and on a message it will get some line data from a variable. That variable will be a array, my script breaks the array down and for each point it flips the x with the y value. It then sends each point as a post request. Is there anyway I can reconstruct the array back together, and then send the post request after flipping each x and y value?
here's my script:
var evtSource = new EventSource("http://URL.com/");
evtSource.onmessage = function(e) {
var obj = JSON.parse(e.data);
var line = JSON.stringify(obj.line)
var line22 = obj.line
//console.log(line22)
line22.forEach(function(point, index){
console.log(JSON.stringify(point)); // console log example// -> "[120,250]"
const [x, y] = point;
console.log(`x: ${x}, y: ${y}`);
var FlipXYvalues = "[[" + y + "," + x + "]]"; // Complies it again... flips the values..
var ident = "String"
if (obj.ident === ident) //the string...
{
$.post("http://URL.com/", {
l: (FlipXYvalues),
w : (obj.lineWidth),
c: (obj.lineColor.replace("#", "")),
o: ("100"),
f: ("1"),
_: ("false")
})
}
});
}

You can use Array#map() to create a new array based on some other array
line22 = [[1,2],[3,4],[5,6],[7,8]];
var newLines = line22.map(point => {
return [point[1], point[0]];
});
//using array destructuring
//if you dont want to mess with specifying indexes
var newLines = line22.map(([x,y]) => {
return [y,x];
});
console.log(JSON.stringify(newLines));
//$.post("http://URL.com/", {l:newLines});

Related

How to make an array of points using JavaScript?

I use JavaScript and Chartjs library to draw charts. I store points data in JSON:
"Chart1":{"1": "4","4": "4","10": "4"}
To draw charts correctly I need to provide input like that:
data:[{x:1,y:4},{x:4,y:4},{x:10,y:4}].
I tried do this this way:
var userData = JSON.parse('{"Chart1":{"1": "4","4": "4","10": "4"}}');
var MyKey = [Object.keys(userData['Chart1'])];
var MyVal = [Object.values(userData['Chart1'])];
var POINTS = []; //I tried also {}
for(b=0; b <= MyKey.length; b++)
{
POINTS.push({x:MyKey[b],y:MyVal[b]});
}
and then in config variable:
data:[POINTS]
but the output is:
[
0:
{
x:["1","4","10"]
y:["4","4","4"]
}
1:
{
x:undefined
y:undefined
}
}
f
So how I should do this correctly?
EDIT:
I corrected json string, I pasted it wrong, it's only a typo but thank you all for vigiliance
You can use Object.entries()
var userData = JSON.parse('{ "Chart1":{"1": "4","4": "4","10": "4"} }');
const data = Object.entries(userData['Chart1']).map(([x, y]) => ({ x, y }));
console.log(data);
Some characters were missing from the json string in your example.
Object.keys and Object.values return arrays, don't enclose them in [].
You're storing strings, but your points probably need numbers for x and y. You can do the conversion with a + operator (or parseInt or Number).
var userData = JSON.parse('{"Chart1":{"1": "4","4": "4","10": "4"}}');
var MyKey = Object.keys(userData['Chart1']);
var MyVal = Object.values(userData['Chart1']);
var POINTS = [];
for (b = 0; b < MyKey.length; b++) {
POINTS.push({
x: +MyKey[b],
y: +MyVal[b]
});
}
console.log(POINTS);
You can do this by using Object.entries to get the keyPair value and then map it so that x = key and y = value.
const x = {Chart1:{"1": "4","4": "4","10": "4"}};
const chartKeyValuePair = Object.entries(x.Chart1);
const xy = chartKeyValuePair.map(([key, value]) => {return {x:key, y: value}});
console.log(xy);
You're overcomplicating it! If you use a for...in loop, you get the key of each property in the data, and you can use that to refer to the value. No need for Object.keys etc. Demo:
var userData = JSON.parse('{"Chart1":{"1": "4","4": "4","10": "4"}}');
var POINTS = [];
for (key in userData.Chart1) {
POINTS.push({
x: key,
y: userData.Chart1[key]
});
}
console.log(POINTS);
N.B. You'll see I made an assumption about the real stucture of the userData JSON string, because what you've posted in the question isn't valid JSON and causes a script error.

CustomJs callbacks not updating data source for plot

I'm trying to update the data source of plot 2 based on the hovered overvalues of plot 1, so that an accompanying viz is created in plot 2 based on the data from plot 1.
Problem is I can get the data out of rect inside of the callback and format it into x and y for a line graph, but it does not update the plot only removes the placeholder values from it.
The data object contains the x and y values that need to be displayed in p2 (the line graph) and are equal length and formatted, not sure why its not changing the sourceLine ColumnDataSource
#hover tool for additional plots
p2 = figure(plot_width = 900, plot_height = 350)
#initial data source
sourceLine = ColumnDataSource(data = {'x': [2, 3, 5, 6, 8, 7], 'y': [6, 4, 3, 8, 7, 5]})
#line to be updated
ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine.data)
#callback
callback = CustomJS(args={'rect': rc.data_source.data, 'line': ln.data_source}, code="""
var rdataYear = rect.YEAR;
var rdataAgeGroup = rect.AGE_GROUP;
var rdataDeaths = rect.DEATHS;
var data = {'x': [], 'y': []};
var deaths = [];
var years = [1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017
]
var indices = cb_data.index['1d'].indices;
var newarr = rect.AGE_GROUP.map((e,i) => e === rdataAgeGroup[indices] ? i : undefined).filter(x => x);
for (var i = 0; i < newarr.length; i++){
var index = newarr[i];
deaths.push(rdataDeaths[index])
}
//data that needs to be inside p2 line
data['x'].push(years)
data['y'].push(deaths)
line.data = data;
line.change.emit();
""")
#hover tool with the callback
p1.add_tools(HoverTool(tooltips=[('Year', '#YEAR'), ('Age Group', '#AGE_GROUP'),('Deaths', '#DEATHS'),('Rate', '#RATE')], callback=callback))
I want to have the output from the callback (data) update x and y of p2.line, im kinda new to python and bokeh is a bit funky so I would really appreciate some help :)
This line is incorrect:
ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine.data)
The value of source should be the ColumnDataSource itself:
ln = p2.line(x = 'x', y = 'y', line_width = 2, source = sourceLine)
When you pass a dict like .data, Bokeh will create an internal CDS for you automatically, as a convenience, but now this new CDS that the glyph uses has nothing to do with the one you update in the callback.
Also, don't use the ['1d'] syntax for selection indices. It has has been deprecated now for a very long time, and will guaranteed be removed for good entirely before the end of this year. Instead:
var indices = cb_data.index.indices
Additionally, your JS is not actually updating the data source correctly. The operation at the end data['y'].push(deaths) actually makes the list of deaths a sublist of the existing empty list, which is not the correct format. Here is an updated version of the JS code:
const rdataYear = rect.YEAR
const rdataAgeGroup = rect.AGE_GROUP
const rdataDeaths = rect.DEATHS
const years = [1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017]
const indices = cb_data.index.indices;
const newarr = rect.AGE_GROUP.map((e,i) => e === rdataAgeGroup[indices] ? i : undefined).filter(x => x);
const deaths = []
for (var i = 0; i < newarr.length; i++){
deaths.push(rdataDeaths[newarr[i]])
}
line.data = {x: years, y: deaths}
Note if you actually assign to .data then Bokeh can detect that automatically, no need for an explicit signal.

How to parse JSON value from MQTT client to plotly javascript

Hi I have this json type data how can I access P , T , F , W and M data using javascript?
{"PHILMG":[{"P":"10"}, {"T":"5"}, {"F":"0"}, {"W":"0"}, {"M":"0"}]}
so far I tried.
function onMessageArrived(message) {
ss = message.payloadString;
console.log(ss);
// var p = ss.PHILMG.P;
// var time = ss.PHILMG.T;
// var f = ss.PHILMG.F;
// var w = ss.PHILMG.W;
// var m = ss.PHILMG.M;
// var timecollect = [];
// var windcollect = [];
// timecollect.push(time);
// windcollect.push(wind);
// console.log(windcollect);
// var data =
// {
// type:'scatter',
// x: time,
// y: w
// };
// Plotly.newPlot(document.getElementById('PhilMg'), data);
}
But Im getting an error
Object {errorCode: 5, errorMessage: "AMQJS0005E Internal error. Error Message: Cannot r…ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js:19:132)"}
Parse your JSON string with JSON.parse, then loop over the array and push the keys and values to the data which is visualized with Plotly.
var message = '{"PHILMG":[{"P":"10"}, {"T":"5"}, {"F":"0"}, {"W":"0"}, {"M":"0"}]}';
var msg = JSON.parse(message);
var x = [];
var y = [];
var i = 0;
var j;
var k;
for (k in msg) {
for (i = 0; i < msg[k].length; i += 1) {
for (j in msg[k][i]) {
x.push(j);
y.push(msg[k][i][j]);
}
}
}
var data = [{
x: x,
y: y,
type: 'bar'
}];
Plotly.newPlot('myDiv', data);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id='myDiv'></div>
You should use the correct index of the array you have in your object to reach the respective inner object at each assignment.
// var p = ss.PHILMG[0].P;
// var time = ss.PHILMG[1].T;
// var f = ss.PHILMG[2].F;
// var w = ss.PHILMG[3].W;
// var m = ss.PHILMG[4].M;
You can see the log in developer tools,
If you see this,
Object {PHILMG: Array[5]}
You should use the index of the array to get the object, then use key to get the value.
If you see this,
"{"PHILMG":[{"P":"10"}, {"T":"5"}, {"F":"0"}, {"W":"0"}, {"M":"0"}]}"
You should use ss = JSON.parse(ss), and same as above.

Dynamically generated object not working as parameter to .css()

I have this function:
function myfunc(obj, properties, value) {
$.each(properties, function(i, key) {
var a = '-webkit-border-' + key + '-radius';
var b = '-moz-border-radius-' + key.replace(/\-/g, '');
var c = 'border-' + key + '-radius';
var z = value+'px';
obj.css({a : z, b: z, c: z});
});
}
Called like this:
myfunc($tab, ['top-left', 'top-right'], defaults.tabRounded);
Note that if I replace the obj.css line with:
obj.css({'border-top-right-radius': value+'px'});
It works as intended. Yet the values of a, b, c are completely correct.
What is going on?
The keys of an object literal in JavaScript are strings, not variables. If you do not quote them yourself, they are auto-quoted. So if you write
var a = {b: 1};
it's the same as if you had written
var a = {'b': 1};
You have to use [] to set keys dynamically.
var a = {};
a[b] = 1;
In this case modify your function to
function myfunc(obj, properties, value) {
$.each(properties, function(i, key) {
var a = '-webkit-border-' + key + '-radius';
var b = '-moz-border-radius-' + key.replace(/\-/g, '');
var c = 'border-' + key + '-radius';
var z = value+'px';
var css = {};
css[a] = css[b] = css[c] = z;
obj.css(css);
});
}

The $.param( ) inverse function in JavaScript / jQuery

Given the following form:
<form>
<input name="foo" value="bar">
<input name="hello" value="hello world">
</form>
I can use the $.param( .. ) construct to serialize the form:
$.param( $('form input') )
=> foo=bar&hello=hello+world
How can I deserialize the above String with JavaScript and get a hash back?
For example,
$.magicFunction("foo=bar&hello=hello+world")
=> {'foo' : 'bar', 'hello' : 'hello world'}
Reference: jQuery.param( obj ).
You should use jQuery BBQ's deparam function. It's well-tested and documented.
This is a slightly modified version of a function I wrote a while ago to do something similar.
var QueryStringToHash = function QueryStringToHash (query) {
var query_string = {};
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
pair[0] = decodeURIComponent(pair[0]);
pair[1] = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = pair[1];
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]], pair[1] ];
query_string[pair[0]] = arr;
// If third or later entry with this name
} else {
query_string[pair[0]].push(pair[1]);
}
}
return query_string;
};
How about this short functional approach?
function parseParams(str) {
return str.split('&').reduce(function (params, param) {
var paramSplit = param.split('=').map(function (value) {
return decodeURIComponent(value.replace(/\+/g, ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
Example:
parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}
My answer:
function(query){
var setValue = function(root, path, value){
if(path.length > 1){
var dir = path.shift();
if( typeof root[dir] == 'undefined' ){
root[dir] = path[0] == '' ? [] : {};
}
arguments.callee(root[dir], path, value);
}else{
if( root instanceof Array ){
root.push(value);
}else{
root[path] = value;
}
}
};
var nvp = query.split('&');
var data = {};
for( var i = 0 ; i < nvp.length ; i++ ){
var pair = nvp[i].split('=');
var name = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
var first = path[1];
if(path[2]){
//case of 'array[level1]' || 'array[level1][level2]'
path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
}else{
//case of 'name'
path = [];
}
path.unshift(first);
setValue(data, path, value);
}
return data;
}
I am using David Dorward's answer, and realized that it doesn't behave like PHP or Ruby on Rails how they parse the params:
1) a variable is only an array if it ends with [], such as ?choice[]=1&choice[]=12, not when it is ?a=1&a=2
2) when mulitple params exist with the same name, the later ones replaces the earlier ones, as on PHP servers (Ruby on Rails keep the first one and ignore the later ones), such as ?a=1&b=2&a=3
So modifying David's version, I have:
function QueryStringToHash(query) {
if (query == '') return null;
var hash = {};
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
var k = decodeURIComponent(pair[0]);
var v = decodeURIComponent(pair[1]);
// If it is the first entry with this name
if (typeof hash[k] === "undefined") {
if (k.substr(k.length-2) != '[]') // not end with []. cannot use negative index as IE doesn't understand it
hash[k] = v;
else
hash[k.substr(0, k.length-2)] = [v];
// If subsequent entry with this name and not array
} else if (typeof hash[k] === "string") {
hash[k] = v; // replace it
// If subsequent entry with this name and is array
} else {
hash[k.substr(0, k.length-2)].push(v);
}
}
return hash;
};
which is tested fairly thoroughly.
I know this is an old thread, but maybe there is still some relevance in it?
Inspired by Jacky Li's good solution I tried a slight variation of my own with the objective to also be able to take care of arbitrary combinations of arrays and objects as input. I looked at how PHP would have done it and tried to get something "similar" going. Here is my code:
function getargs(str){
var ret={};
function build(urlnam,urlval,obj){ // extend the return object ...
var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
while (x=rx.exec(urlnam)) idx.push(x[1]);
while(true){
k=idx.shift();
if(k.trim()=='') {// key is empty: autoincremented index
if (o.constructor.name=='Array') k=o.length; // for Array
else if (o===obj ) {k=null} // for first level property name
else {k=-1; // for Object
for(i in o) if (+i>k) k=+i;
k++;
}
}
if(idx.length) {
// set up an array if the next key (idx[0]) appears to be
// numeric or empty, otherwise set up an object:
if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[];
o=o[k]; // move on to the next level
}
else { // OK, time to store the urlval in its chosen place ...
// console.log('key',k,'val',urlval);
o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
}
}
return obj;
}
// ncnvt: is a flag that governs the conversion of
// numeric strings into numbers
var ncnvt=true,i,k,p,v,argarr=[],
ar=(str||window.location.search.substring(1)).split("&"),
l=ar.length;
for (i=0;i<l;i++) {if (ar[i]==="") continue;
p=ar[i].split("=");k=decodeURIComponent(p[0]);
v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
argarr.push([k,v]); // array: key-value-pairs of all arguments
}
for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
return ret;
}
If the function is called without the str-argument it will assume window.location.search.slice(1) as input.
Some examples:
['a=1&a=2', // 1
'x[y][0][z][]=1', // 2
'hello=[%22world%22]&world=hello', // 3
'a=1&a=2&&b&c=3&d=&=e&', // 4
'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc', // 5
$.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')
results in
{"a":2} // 1
{"x":{"y":[{"z":[1]}]}} // 2
{"hello":"[\"world\"]","world":"hello"} // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]} // 5
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]} // 6
{"a":["hi",2,null,[7,99],13]} // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}} // 8
Whereas Jacky Li's solution would produce the outer container for a as a plain object
{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output
getargs() looks at the first given index for any level to determine whether this level will be an object (non-numeric index) or an array (numeric or empty), thus resulting in the output as shown in the listing bove (no. 6).
If the current object is an array then nulls get inserted wherever necessary to represent empty positions. Arrays are always consecutively numbered and 0-based).
Note, that in the example no. 8 the "autoincrement" for empty indices still works, even though we are dealing with an object now and not an array.
As far as I have tested it, my getargs() behaves pretty much identically to Chriss Roger's great jQuery $.deparam() plugin mentioned in the accepted answer. The main difference is that getargs runs without jQuery and that it does autoincrement in objects while $.deparam() will not do that:
JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);
results in
{"3":["7","99"],"x":"hi","undefined":"13"}
In $.deparam() the index [] is interpreted as an undefined instead of an autoincremented numerical index.
Here's how you could create a new jQuery function:
jQuery.unparam = function (value) {
var
// Object that holds names => values.
params = {},
// Get query string pieces (separated by &)
pieces = value.split('&'),
// Temporary variables used in loop.
pair, i, l;
// Loop through query string pieces and assign params.
for (i = 0, l = pieces.length; i < l; i++) {
pair = pieces[i].split('=', 2);
// Repeated parameters with the same name are overwritten. Parameters
// with no value get set to boolean true.
params[decodeURIComponent(pair[0])] = (pair.length == 2 ?
decodeURIComponent(pair[1].replace(/\+/g, ' ')) : true);
}
return params;
};
Thanks to him http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
Pretty easy :D
function params_unserialize(p){
var ret = {},
seg = p.replace(/^\?/,'').split('&'),
len = seg.length, i = 0, s;
for (;i<len;i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;}
This is really old question, but as i have coming - other people may coming to this post, and i want to a bit refresh this theme. Today no need to make custom solutions - there is URLSearchParams interface.
var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);
//Iterate the search parameters.
for (let p of searchParams) {
console.log(p);
}
The only one limitation i know - this feature not supported in IE / Edge.
Here's my JavaScript implementation which I use in a server-side JScript ASP Classic page (demo):
// Transforms a query string in the form x[y][0][z][]=1 into {x:{y:[{z:[1]}]}}
function parseJQueryParams(p) {
var params = {};
var pairs = p.split('&');
for (var i=0; i<pairs.length; i++) {
var pair = pairs[i].split('=');
var indices = [];
var name = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]);
var name = name.replace(/\[([^\]]*)\]/g,
function(k, idx) { indices.push(idx); return ""; });
indices.unshift(name);
var o = params;
for (var j=0; j<indices.length-1; j++) {
var idx = indices[j];
var nextIdx = indices[j+1];
if (!o[idx]) {
if ((nextIdx == "") || (/^[0-9]+$/.test(nextIdx)))
o[idx] = [];
else
o[idx] = {};
}
o = o[idx];
}
idx = indices[indices.length-1];
if (idx == "") {
o.push(value);
}
else {
o[idx] = value;
}
}
return params;
}
I came up with this solution, which behaves like the .Net function HttpUtility.ParseQueryString.
In the result, the query string parameters are store in properties as lists of values, so that qsObj["param"] will be the same as calling GetValues("param") in .Net.
I hope you like it. JQuery not required.
var parseQueryString = function (querystring) {
var qsObj = new Object();
if (querystring) {
var parts = querystring.replace(/\?/, "").split("&");
var up = function (k, v) {
var a = qsObj[k];
if (typeof a == "undefined") {
qsObj[k] = [v];
}
else if (a instanceof Array) {
a.push(v);
}
};
for (var i in parts) {
var part = parts[i];
var kv = part.split('=');
if (kv.length == 1) {
var v = decodeURIComponent(kv[0] || "");
up(null, v);
}
else if (kv.length > 1) {
var k = decodeURIComponent(kv[0] || "");
var v = decodeURIComponent(kv[1] || "");
up(k, v);
}
}
}
return qsObj;
};
Here is how to use it:
var qsObj = parseQueryString("a=1&a=2&&b&c=3&d=&=e&");
To preview the result in the console juste type in:
JSON.stringify(qsObj)
Output:
"{"a":["1","2"],"null":["","b",""],"c":["3"],"d":[""],"":["e"]}"
There's a beautiful one-liner over at CSS-Tricks (original source from Nicholas Ortenzio):
function getQueryParameters(str) {
return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}
The really clever part is how it uses the anonymous function's this object, adding a key/value pair for each of the queries in the string. That said, there's some room for improvement. I've modified it a bit below, with the following changes:
Added handling of empty strings and non-string input.
Handled URI-encoded strings (%40->#, etc).
Removed the default use of document.location.search when the input was empty.
Changed the name, made it more readable, added comments.
function deparam(str) {
// Uses an empty 'this' to build up the results internally
function splitQuery(query) {
query = query.split('=').map(decodeURIComponent);
this[query[0]] = query[1];
return this;
}
// Catch bad input
if (!str || !(typeof str === 'string' || str instanceof String))
return {};
// Split the string, run splitQuery on each piece, and return 'this'
var queries = str.replace(/(^\?)/,'').split('&');
return queries.map(splitQuery.bind({}))[0];
}
use this :
// convert query string to json object
var queryString = "cat=3&sort=1&page=1";
queryString
.split("&")
.forEach((item) => {
const prop = item.split("=");
filter[prop[0]] = prop[1];
});
console.log(queryString);
This is my version in Coffeescript.
Also works for url like
http://localhost:4567/index.html?hello=[%22world%22]&world=hello#/home
getQueryString: (url)->
return null if typeof url isnt 'string' or url.indexOf("http") is -1
split = url.split "?"
return null if split.length < 2
path = split[1]
hash_pos = path.indexOf "#"
path = path[0...hash_pos] if hash_pos isnt -1
data = path.split "&"
ret = {}
for d in data
[name, val] = d.split "="
name = decodeURIComponent name
val = decodeURIComponent val
try
ret[name] = JSON.parse val
catch error
ret[name] = val
return ret
Here's a simple & compact one if you only want to quickly get the parameters from a GET request:
function httpGet() {
var a={},b,i,q=location.search.replace(/^\?/,"").split(/\&/);
for(i in q) if(q[i]) {b=q[i].split("=");if(b[0]) a[b[0]]=
decodeURIComponent(b[1]).replace(/\+/g," ");} return a;
}
It converts
something?aa=1&bb=2&cc=3
into an object like
{aa:1,bb:2,cc:3}
Creates a serialized representation of an array or object (can be used as URL query string for AJAX requests).
<button id='param'>GET</button>
<div id="show"></div>
<script>
$('#param').click(function () {
var personObj = new Object();
personObj.firstname = "vishal"
personObj.lastname = "pambhar";
document.getElementById('show').innerHTML=$.param(`personObj`));
});
</script>
output:firstname=vishal&lastname=pambhar
answers could use a bit of jQuery elegance:
(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
var params = {}, e;
while ( e = re.exec(query) ) {
var k = decode( e[1] ), v = decode( e[2] );
if (k.substring(k.length - 2) === '[]') {
k = k.substring(0, k.length - 2);
(params[k] || (params[k] = [])).push(v);
}
else params[k] = v;
}
return params;
};
})(jQuery);
fork at https://gist.github.com/956897
You can use the function .serializeArray() (Link) of jQuery itself. This function returns an array of key-value pair. Result example:
[
{ name: "id", value: "1" },
{ name: "version", value: "100" }
]

Categories