Get variables from URL and convert to array - javascript

I need to retrieve variables from an URL.
I use this found function:
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
return obj;
}
var urlexample = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
The output is:
{"idPagamenti":["26","27"],"idCliente":["9"]}
But idCliente is always NOT an array, so i'd like to retrieve:
{"idPagamenti":["26","27"],"idCliente": 9 }
This is the fiddle example
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
return obj;
}
var stringa = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
$(document).ready(function(){
alert("testing");
console.log(me);
$(".a").html(JSON.stringify(me));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">
</div>
Someone can help me to modify code?

I think your facing a real paradigm problem. Why idCliente wouldn't be an array but idPagamenti would be. You should have all array or none but not both. getParams() function can make this choice for you and you should probably change the way you are working with this.
Anyway, here is a getParams() function that replace any single-valued array to a value. Note that if you have only one idPagamenti in your URI, you will also have a single value for idPagamenti instead of an array.
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
Object.keys(obj).forEach(key => {
if (obj[key].length === 1) {
obj[key] = obj[key][0];
}
})
return obj;
}
var urlexample = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
If you know that you will always get ids as parameters, you can also add a parseInt() for each parameter by replacing var value = spl[1]; with var value = parseInt(spl[1], 10);

Related

Javascript looping through variables

So right now this is my current code and I'm trying to figure out a way to loop through the variables I've already declared (Assuming variables 1-9 already have values). I just wanted to know whether this was possible at all?
var title;
var brief;
var hover;
var whatTitle;
var whatDesc;
var whyTitle;
var whyDesc;
var funTitle;
var funDesc;
var titles = [];
var briefs = [];
var hovers = [];
var whatTitles = [];
var whatDescs = [];
var whyTitles = [];
var whyDescs = [];
var funTitles = [];
var funDescs = [];
var obj = {'titles' : title};
if(localStorage.getItem('titles') != null) {
var tmp = JSON.parse(localStorage.getItem('titles'));
for(var i = 0;i<tmp.length;i++) {
titles.push(tmp[i]);
}
}
titles.push(obj);
localStorage.setItem("titles", JSON.stringify(titles));
Output I want if we printed out the looped code:
var obj = {'titles' : title};
if(localStorage.getItem('titles') != null) {
var tmp = JSON.parse(localStorage.getItem('titles'));
for(var i = 0;i<tmp.length;i++) {
titles.push(tmp[i]);
}
}
titles.push(obj);
localStorage.setItem("titles", JSON.stringify(titles));
var obj = {'briefs' : brief};
if(localStorage.getItem('briefs') != null) {
var tmp1 = JSON.parse(localStorage.getItem('briefs'));
for(var i = 0;i<tmp.length;i++) {
briefs.push(tmp[i]);
}
}
briefs.push(obj);
localStorage.setItem("briefs", JSON.stringify(briefs));
var obj = {'hovers' : hover};
if(localStorage.getItem('hovers') != null) {
var tmp2 = JSON.parse(localStorage.getItem('hovers'));
for(var i = 0;i<tmp.length;i++) {
hovers.push(tmp[i]);
}
}
hovers.push(obj);
localStorage.setItem("hovers", JSON.stringify(hovers));
...etc
If the code is running in a browser, then you can do something like:
for(key in window) { console.log(window[key]) } // print all variables
The variables are associated to the global namespace. That is to say the upmost "this" reference or the window object.
You're almost there with the code you have. If you look at your "desired output" examples, you'll see that the only thing that really differs between each element of your "unrolled loop" is the key for local storage ('titles', 'briefs', 'hovers').
With that in mind, you could use an Object to map the keys to the variables you have at the top level. So this:
var titles = [];
var briefs = [];
var hovers = [];
var whatTitles = [];
var whatDescs = [];
...
Becomes (UPDATE: with the initializer values preserved):
var key_to_collection = {
'titles': [title],
'briefs': [brief],
'hovers': [hovers],
'whatTitles': [whatTitles],
'whatDescs': [whatDescs],
}
Then, you loop over the values of this object:
Object.keys(key_to_collection).forEach(function(key) {
var obj = {};
collection = key_to_collection[key];
obj[key] = collection;
if(localStorage.getItem(key) != null) {
var tmp = JSON.parse(localStorage.getItem(key));
for(var i = 0;i<tmp.length;i++) {
collection.push(tmp[i]);
}
}
collection.push(obj);
localStorage.setItem(key, JSON.stringify(collection));
});
If your variable name is title for example, then you can access it using window['title']. This means that if you define an array of your global variable names:
const varNames = ['title', 'brief', 'hover', ...]
Then you can do a loop like the following
for(const name of varNames) {
const value = window[name]
// do whatever you want using the variable name and value
}
I hope this solves your issue :)

Determine all attributes of a Javascript variable accessed inside a function WITHOUT running it

Is there a clever way to figure out all attributes of an object referenced within a function WITHOUT executing it?
For example let's say I have the following function:
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
I would like some magical function that does:
var results = magical_function(fun, {});
// results = ["text", "title", "ran"];
Basically it's returning all attributes of the argument object that will be accessed inside the fun function, WITHOUT having to actually execute fun.
I said "without running" it because I don't want the act of checking this affect any outside app logic, but I am fine as long as the checking doesn't influence the outside world.
function.toString() is going to return a parsable string. Use Regex on that.
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
var fun2 = function(x){
x.text = "hello world";
x.title = "greetings";
a.ran = "fun";
}
function magical_function(func) {
var data = func.toString();
var r = /a\.([a-z]+)/g;
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
matches.push(match[1]);
}
return matches;
}
function magical_function_2(func) {
var data = func.toString();
var attribute_finder_r = new RegExp('function \\(([a-z]+)\\)');
var attribute_name_match = attribute_finder_r.exec(data);
if (!attribute_name_match) {
throw 'Could not match attribute name';
}
var attribute_name = attribute_name_match[1];
var r = new RegExp(attribute_name + '.([a-z]+)', 'g');
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
matches.push(match[1]);
}
return matches;
}
console.log(magical_function(fun));
console.log(magical_function_2(fun2));
var myObj = {
text: '',
title: '',
ran: ''
}
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
function magical_function(func, obj) {
var data = func.toString();
var keys = Object.keys(obj);
var regExp = '';
for (let i= 0; i < keys.length; i++) {
if (keys.length > 1 && ((i+1) < keys.length)) {
regExp += keys[i] + '|';
}
else if (keys.length == 1 || ((i+1) == keys.length)) {
regExp += keys[i];
}
}
regExp = '\.(['+ regExp +']+)\\s*=';
var r = new RegExp(regExp, 'g');
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
if (Object.keys(obj).includes(match[1]))
matches.push(match[1]);
}
return matches;
}
console.log(magical_function(fun, myObj));
There's no way those attributes are going to get set before running the function.
The only thing you can do is to write another version of the function which only accesses the object passed and returns the result.

Calling an array item into another array

I faced the following functions (or method I don't what is right name of the ):
function getRowArray($scope, object, i){
i = i + 1;
var item = {};
var data = [];
var id = -1;
if ($scope.selectedType !== undefined) {
id = $scope.selectedType.id;
}
var rating = getRating($scope, object, id);
item['name'] = $scope.objectInfo[object]['name'];
item['objectId'] = rating.objectId;
item['hideRating'] = parseInt($scope.objectInfo[object].hideControls) & 1;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
item['ratingId'] = rating.id;
for (var i in $scope.objectInfo[object].childs) {
if ($scope.objectInfo[object].childs[i] == object){
continue;
}
data.push(getRowArray($scope, $scope.objectInfo[object].childs[i], i));
}
item['data'] = data;
return item;
}
and
function getTypeRow($scope, oobject, otype){
var item = {};
var data = [];
var rating = getRating($scope, oobject.id, otype.id);
item['name'] = otype.name;
item['objectId'] = rating.objectId;
item['typeId'] = rating.typeId;
item['ratingId'] = rating.id;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
// item['hideRating'] = parseInt($scope.objectInfo[object].hideControls);
return item;
}
I want to use the hideRating item from the first one in the second, I tried and added the commented line but I got an error it says the object is undifined, is it wrong like that or am I missing something ? thanks in advance
object is undefined because it wasn't initialized; it's not specified in the parameter list for the function getTypeRow. The oobject in the parameter list should be corrected to object:
// Correct 'oobject' to 'object'
function getTypeRow($scope, object, otype){
var item = {};
var data = [];
// Correct 'oobject' to 'object'
var rating = getRating($scope, oobject.id, otype.id);
...
}

Extract value from certain query from string in jQuery

var test = "http://www.example.org/search?q=whatever&another=moretext";
How can I extract another's value (moretext) in the query string above and make a variable out of it?
var test = "http://www.example.org/search?q=whatever&another=moretext";
var another = test.split('another=');
another is an array with another[0] = 'http://www.example.org/search?q=whatever&' and another[1] = 'moretext'.
keep this function in your bag :
function querySt(qsName, url)
{
var theUrl;
if (url == null || url == undefined)
theUrl = window.location.search.substring(1); else theUrl = url;
var g = theUrl.split("&");
for (var i = 0; i < g.length; i++) {
var pair = g[i].split("=");
if (pair[0].toLowerCase() == qsName.toLowerCase())
{
return pair[1];
}
}
return null;
}
Usages
alert(querySt("another")+' '+querySt("q"));

Add a property to an object returned by a function?

I would like to know if there is a way to get all properties of 'myFields' assigned in a single statement ?
This works:
function fieldMap(namesString) {
var result = {};
var names = namesString.split(' ');
for (index in names) {
var name = names[index];
result[name] = name + '/text()';
}
return result;
}
var myFields = fieldMap('title rating author url');
myFields['cover']="#cover";
This doesn't work:
var myFields = fieldMap('title rating author url')['cover']='#cover';
If you want to change all properties of an object in a single statement, you have to write yourself a mapping method:
function fieldMap(namesString) { // Mike Lin's version
var result = {};
var names = namesString.split(' ');
for (var i=0; i<names.length; i++) {
var name = names[i];
result[name] = name + '/text()';
}
return result;
}
Object.prototype.map = function(callbackOrValue){
/* better create an object yourself and set its prototype instead! */
var res = {};
for(var x in this){
if(typeof this[x] === "function")
res[x] = this[x];
if(typeof callbackOrValue === "function")
res[x] = callbackOrValue.call(this[x]);
else
res[x] = callbackOrValue;
}
return res;
}
Then you can use
var myFields = fieldMap('title rating author url').map(function(){return '#cover'};
/* ... or ... */
var myFields = fieldMap('title rating author url').('#cover');
However, if you want to set myFields and change the value in the same step, try this:
var myFields;
(myFields = fieldMap('title rating author url'))['cover']='#cover';

Categories