At the moment I have to check every potentially existing parameter separately.
if (req.query.param1 != undefined ) {
}
if (req.query.param2 != undefined ) {
}
if (req.query.param3 != undefined ) {
}
...
To get all query parameter:
Object.keys(req.query)
To get number of all params:
Object.keys(req.query).length
Then you can iterate through all parameters:
for(p in req.query) {
//... do something
}
UPD:
surround your request with quotes to make right query
curl -X GET "localhost:9090/mypath?param1=123¶m2=321"
without quotes the & in terminal makes the command run in the background.
If you hit /mypath?param1=5¶m2=10, then the request.query will yield {param1: 5, param2:10}.
This means that the request.query is a JavaScript object with the key as the name of the param, and value as the value of the param. Now you can do anything with it as you want: Find the length or iterate over it as follows:
for (var key in request.query) {
if (request.query.hasOwnProperty(key)) {
alert(key + " -> " + request.query[key]);
}
}
Finding only the length might not work for you that well because you may have param1 and param3, with param2 missing. Iterating will be better IMO.
You want the number of non-undefined params right?
It is as simple as this;
var no = 0;
for (var key in req.query) {
if(req.query[key]) no++;
}
Related
How to get the Object from a string?
I written a localStorage util, in it there are get and set methods.
in the set method:
function fnGet(name){
var getVal=storage.getItem(name);
if(getVal==null){
return console.log('the localstorage did\'t have'+name);
}
if((getVal.split(':-:')).lenght>1){
return eval('('+getVal.split(':-:')[0]+')');
}
return getVal.split(':-:')[0];
}
You can ignore the :-:, it is the separator of the saved data and timestamp.
there is a problem, if the data is stored a JavaScript Object, such like this:
'{"pk":1,"username":"test01","email":"","first_name":"","last_name":""}:-:1521381469910'
when I use the get method, it will become like this:
'{"pk":1,"username":"test01","email":"","first_name":"","last_name":""}'
How can I get to the JavaScript Object?
How to optimize my get method?
JSON.parse on your response from the store. localStorage stores everything as strings so you would need to stringify the object at first, as Im supposed you do as otherwise you wouldnt have been able to save it to the store.
Then to retrieve it you would need to parse it to get the javascript object again.
Two things:
Use JSON.parse() instead of eval; it's not only safer, but more descriptive as to what your intent is. Note: this requires using JSON.stringify() on the data being saved in localStorage
Correct your spelling errors; you would never get to the eval/parser block because your length was spelled "lenght"
function fnGet(name) {
let getVal = storage.getItem(name)
if (getVal == null) {
return console.log(`the localstorage did't have: ${name}`);
}
let val = getVal.split(':-:'); // for performance cache the split
if (val.length > 1) { // Spelling error: "lenght" -> length
return JSON.parse(val[0]);
}
return val[0];
}
LocalStorage saves the data stringified. So you should use JSON.parse(yourVariable) to get the data back as JSON
function fnGet(name) {
var getVal = storage.getItem(name);
if (getVal == null) {
return console.log('the localstorage did\'t have' + name);
}
if ((getVal.split(':-:')).lenght > 1) {
return eval('(' + JSON.parse(getVal.split(':-:')[0]) + ')');
}
return getVal.split(':-:')[0];
}
all you needed was JSON.parse which takes a string as an argument and if its a valid object string ,returns an object else throws an error
I have two APIs which requires two different query string/param structure, I have been trying to figure it out myself how to do this but I'm not getting anywhere.
Both APIs are GET request however API 1 URL request is something like
www.website.com/api/User?username=niceguy
API 2 request URL, because this doesn't have an input its basically just a click of a button to do its search, whereas the API 1 does have an input to build its query string structure.
www.website.com/api/User
Two different query strings but returns the same objects, I'm only using 1 search function for dynamic purpose therefore I'm finding it hard to construct my query string.
I created a function to build the query string however it only takes the API 1 structure.
Can someone point out how the HTTP request can also take API 2 structure?
function queryStringBuild() {
let result: string = "?";
//for each of the input search terms...
this.searchBoxCount.forEach((inputSearch: any) => {
// first reparse the input values to individual key value pairs
// Checks which field is not null and with empty string (space)
if (inputSearch.value != null && (inputSearch.value != "")) {
let inputValues: string = inputSearch.value
.split("\n")
.filter(function (str) { return str !== "" })
.join("&" + inputSearch.name + "=");
// then add it to the overall query string for all searches
result = result + inputSearch.name + "=" + inputValues + "&"
}
});
// remove trailing '&'
result = result.slice(0, result.length - 1);
return result;
}
API request
getRequest() {
this.http.get('www.website.com/api/' + this.queryStringBuild)
...
}
I'd propose a different solution by using URLSearchParams.
let params = new URLSearchParams();
this.searchBoxCount.forEach((inputSearch: any) => {
if (inputSearch.value != null && (inputSearch.value != "")) {
let filteredValue = inputSearch.split("\n")
.filter(x => x != "")
.join(",");
params.set(inputSearch.name, filteredValue);
}
}
this.http.get('www.website.com/api', { search: params });
I don't know exactly how your API works, so how multiple values for the same parameter get concatenated is up to you.
See this post for more information
I'm running into a maddening problem where I set a variable to point to a jQuery selector, such as: var foobar=jQuery(this); I then pass this variable to a function to be worked on. Let's simplify a little and say the function looks like this:
function SetFieldValue (selector) {
selector.val('test');
console.log ( selector );
console.log ( jQuery('#' + selector.attr('id')) );
}
In this situation if you assume that:
the selector is always a form element (and therefore val() is a valid operation)
the selector does resolve to a single dom element which has an 'id' attribute
You would then expect the two console.log statements to output the same result, right? Well I'm running into a situation where this condition only happens about 90% of the time.
In order to give more context I've created a short screencast demonstrating the problem:
SCREENCAST LINK
For reference purposes, here's the actual SetFieldValue code that is shown in the screencast:
function SetFieldValue ( domObject, value ) {
// as a safety function, check if a string representation of the domObject was passed in and convert it to a jQuery object if it was
if ( jQuery.type(domObject) === "string") {
console.log ("Value passed into SetFieldValue was a string representation so converting to jQuery object");
domObject = jQuery(domObject);
}
if ( jQuery.inArray (domObject.prop('tagName').toLowerCase(),['input' , 'select' , 'textarea']) >= 0 ) {
console.log ("setting to value attribute: " + value);
if ( domObject.hasAttr('id') ) {
domObject.val(value);
//jQuery('#' + domObject.attr('id')).val(value);
} else {
domObject.attr('value',value);
}
console.log ("Using jQuery ID it is set to: " + jQuery('#' + domObject.attr('id')).val() );
console.log ("Using jQuery selector variable it is set to: " + domObject.val() );
} else {
console.log ("setting to html attribute");
domObject.html( value );
}
return domObject;
}
Lets examine the code a bit.
First assigning back to a parameter is not a good practice adding a var at the start of your function would be a lot better, as scope can be lost.
//Suggestion change parameter to domItem
var domObject
Your missing an error handler for when the parameter is not String.
when identifying the type use
<VARNAME>.constructor.toString().match(/function (\w*)/)[1] === "<TYPE>"
It's more efficient and handles custom types.
No need for all the logic in assignment of value attribute. Any dom Object can be made to have a value attribute. also not sure why you are setting the val versus the value.
domObject.attr('value',value);
It is at this point that I can see your code could really use some documentation to help explain purpose
If you are explicitly only wanting to set value on Input fields and set value as innerhtml on non input fields then yes the logic would be needed but could be simplified to ... as the value doesn't need to be detected to overwritten.
if (jQuery.inArray (domObject.prop('tagName').toLowerCase(), ['input' , 'select' , 'textarea']) >= 0) {
domObject.attr('value',value);
} else {
domObject.html( value );
}
No Idea why you are returning the domObject out.
So a quick rewrite without the return and keeping most of the logic adding error handling results in
/*jslint sloppy: true*/
/*global jQuery*/
function SetFieldValue(domString, value) {
// as a safety function, check if a string representation of the domObjects was passed in and convert it to a jQuery object if it was
var domObjects, index;
//errorhandling
if (domString === undefined || domString === null) {
throw {error : "domString must have a value."};
}
if (domString.constructor.toString().match(/function (\w*)/)[1] !== "string") {
if (domString.constructor.toString().match(/function (\w*)/)[1].match(/HTML[a-zA-Z]*Element/) === null) {
throw {error : "domString expected to be String or domObjects"};
}
} else {
if (jQuery(domString).length === 0) {
throw {error : "domString does not resolve to a detectable domObjects."};
}
}
//errorhandling
//action
if (domString.constructor.toString().match(/function (\w*)/)[1].match(/HTML[a-zA-Z]*Element/)) {
//made as an array to normalize as jQuery returns an array allows code to be simplified
domObjects = [domString];
} else {
domObjects = jQuery(domString);
}
//given that domObjects are an array need to step through the array
for (index = domObjects.length - 1; index >= 0; index -= 1) {
if (
jQuery.inArray(
domObjects[index].tagName.toLowerCase(),
['input', 'select', 'textarea']
) >= 0
) {
if (domObjects[index].hasAttr('id')) {
domObjects[index].val(value);
} else {
domObjects[index].attr('value', value);
}
} else {
domObjects[index].html(value);
}
}
}
The above passes JSLint
I know I didn't provide enough context for people to really dig into this problem but I have in the end solved it. What was the issue? Well it was #Kobi who first asked is the DOM element's ID unique ... to which I happily reported it was. And it had been but in fact that WAS the problem. Jesus. It's always the obvious things that you then go onto overlook that get you in trouble.
Anyway, thanks for your patience and help.
I'd like to know how to check an array that got several variables in it.. something like that.
I can explain better with the code shown:
// Ignore the words in here, they are just there to explan.
var $array = [
alpha = {
name : $('.a'),
date : $('.b'),
street: $('.c')
},
beta = {
name : $('.x'),
date : $('.y'),
street: $('.z')
}
];
/* So now I got this arrays.. withing an array? is that correct?
* or what is this called?
* and now I want to check each object's length, if its 0 -> return false and
* throw out an error, if >= 1 go on and check the next. */
// Check if all needed elements for the toggle to work are existent
$.each( $array, function(key, value) {
if ( !value.length ) {
alert("Could not find "+ '"' + value.selector +'"!')
return false
};
});
// Well obviously this doesnt work..
Thanks in advance!
You can loop over the names of properties of an object with a for (... in ...) loop:
/* since the array isn't a jQuery object, don't prefix the name with `$` */
var things = [
/* array elements have integer, not string, indices. In any case,
"alpha = ..." is the wrong syntax to set properties. What it
does is set a variable named "alpha".
*/
{...},
{...},
];
$.each(things, function(idx, item) {
for (p in item) {
if (! item[p].length) {
/* alerts are disruptive; use other means of informing
the user or developer.
*/
//alert("Could not find "+ '"' + value.selector +'"!')
return false;
} /* blocks don't need semicolon separators */
}
});
See also "For .. in loop?"
In a JQuery getJSON call, how can I tell the length of the JSON that's returned?
function refreshRoomList() {
$.getJSON('API/list_rooms',
function (rooms) {
if (rooms.length > 0) {
$("#existing-room-list").empty();
$("#join-existing-room").text("Join existing room:"); // this shouldn't be here
$.each(rooms, function (index, roomName) {
var newChild = sprintf('<li>%s</li>', index, roomName);
$("#existing-room-list").append(newChild);
});
}
else {
$("#join-existing-room").text("No rooms found.");
}
});
}
For some reason this doesn't work, but if I replace rooms.length > 0 with true, the full list of rooms is printed out.
If rooms is empty, it is returned as {}.
If rooms is empty, it is returned as {}.
Thus, it's not an array, but an object. Objects doesn't have a length. There's only one of it. If you want to denote nothing, then rather use null instead of {}. This way you can use if (rooms) instead.
To learn more about JSON, you may find this article useful.
Try this approach instead, in your situation it should be null when empty:
if (rooms) {