How to add to URL? - javascript

I am creating a filtering functionality and I would like to add the selected filters to the url for navigation purposes. Here is an array of objects:
let arr = [
{available:true},
{variantOption:{name:"size",value:"2XL"}},
{productType:"Apparel"}
]
I need it in the following format which I think are according to the W3c guidelines:
www.whatever.com/collection?available=true&productType=apparel&somethingElse=something etc
I am not able to figure out how to add something like variantOption key and values to the url in format like so. So that when I retrieve the values from the URL, they end up in the same format like the original array of objects was, which I want to use for the api call.
I would be using window.history.pushState for this use case here.

You will need to loop through the array.
for (let item of arr) {
then you will need to get each key of the object (item).
for (let key in item)
because one of them is another object you will need to check if the value is object
if (typeof item[key] === "object")
if true,
you need to loop one more time to get the extra key value pairs and pass them to the url as params..
for (let innerKey in item[key]) {
newLink.searchParams.set(innerKey, item[key][innerKey]);
else,
just take the key and value and pass them to the url as params.
newLink.searchParams.set(key, item[key]);
the loop at the end should look like this:
const newLink = new URL(window.location.href); // here you can put any base url
for (let item of arr) {
for (let key in item) {
if (typeof item[key] === "object") {
for (let innerKey in item[key]) {
newLink.searchParams.set(innerKey, item[key][innerKey]);
}
} else {
newLink.searchParams.set(key, item[key]);
}
}
}
and then to use the newLink.href as the url. you mentioned that you want to use window.history.pushState . so you can call the function and pass the url as argument.
example here: codesandbox example

Related

How to filter the dynamic Json data using underscore.js?

I have an array of json objects with dynamic data in it i.e both the keys and values are dynamic as :
arr=[{"a":"email"},{"b":"chat"},{"c":"email"},{"d":"chat"},{"e":"email"}]
The size of arr may change i.e it may have any number of json objects.
How do I filter the data using underscore.js ??
This is what I was trying to do :
filterData(searchValue:string){
this.skillGrpsFilteredData= _.filter(this.skillGroupsAndTypes, function(obj) {
return ~obj.toLowerCase().includes(searchValue) as any;
});
}
But this approach is not working as the keys in the above array obj is dynamic i.e "a,b,c,d,e,.." are dynamic in nature.
And searchValue is the value that comes from the frontend UI.
How do I perform search using keys i.e if I type searchValue=a it should give me that object and so on .
Thanks & Regards
Try the following function. In the array parameter you can pass arr=[{"a":"email"},{"b":"chat"},{"c":"email"},{"d":"chat"},{"e":"email"}] and in searchKey parameter pass such as "a" it will return {"a":"email"}. If match not found function will return null
searchByKey(array,searchKey ) {
for (let obj of array) {
for (let key in obj) {
if (key == searchKey) {
return obj;
}
}
}
return null;
}
Try this
Following function filters array objects containing the search value both in key and value of the object
in your case you can pass 'a' or "email" to get the objects
function searchObject(array , searchValue){
return array.filter(item=>{ return Object.keys(item).includes(searchValue) ||Object.values(item).includes(searchValue)})
}
let arr=[{"a":"email"},{"b":"chat"},{"c":"email"},{"d":"chat"},{"e":"email"}]
console.log(searchObject(arr,'a'));
if you want just to filter by key and not by value of the object remove the
Object.values(item).includes(searchValue)
from the or condition
if you want to try indexOf
try
function searchObject(array , searchValue){
return array.filter(item=>{ return
Object.keys(item).indexOf(searchValue)>=0})
}

Parsing Json in Node.js which holds numbers as its key param

My JSON holds numbers in its key param for an example:
"abc_12345_xyz":"value".
I am fetching this 12345 from my property file and framing the key param dynamically, while parsing it. For an example
var num=fetching from prop file(12345).
var jsonValue=jsonObj.value[0].abc_+num+_xyz
I am not getting the value while performing the above step, is there anyway to frame the key parameter dynamically.
Try using
jsonObj.value[0]["abc_"+num+"_xyz"]
If you will have a list in your properties file and want to get the value based on the entry, like using a regex to get any key that have the property content, you can loop through the keys and check if it have the word on the key. See below this example:
var obj = {
"abc_12345_xyz": "test_value_1",
"abc_qwert_xyz": "test_value_2"
};
var prop_file = [12345, 'qwert'];
for (var key in obj) {
if (key.indexOf(prop_file[1]) > -1) {
console.log(key, obj[key]);
}
}
Or if the key will always having the prefix and suffix static, you can simply:
obj["abc_"+ prop_value +"_xyz"];

how to insert new object in node js array if key not exist

I want to create data structure like that.
Var ans =[{"b":[1,2]},{"g":[100,2]}]
I want to create a new object within list if key not exists in list ans.
Else if key exists in one object of ans list then I want to add new values into the object of ans list
For Example:
Example 1) new data c:{2000}
then
Var ans =[{"b":[1,2]},{"g":[100,2]},{c:[2000]}]
Example 2) new data g:{50}
then
Var ans =[{"b":[1,2]},{"g":[100,2,500]},{c:[2000]}]
I am a beginner in node js, understand array, object concept, but not getting exact logic!
Thanks!
You can try following:
Logic
Filter array based on key
Check if object with mentioned key exists or not.
If yes, push value to this array.
If not, create a dummy object and push this object to original array.
Correction, when you do .push({key: value}), key will be considered as string.
Alternates
If you are using ES6, .push({ [key] : value })
Create a dummy object var o = {}. Set key and value to it o[key] = value and push this object.
Optimisations
Instead of setting value like obj[key] = value, since we will be operating on arrays, try obj[key] = [].concat(value). This will enable you to pass value as number or array of values.
Instead of checking the existence of value in .filter, try Array.isArray to check if value exists and is of type array.
Custom function
function checkAndPush(array, key, value) {
var filteredList = array.filter(function(o) {
return Array.isArray(o[key]);
});
filteredList.length > 0 ? filteredList[0][key].push(value) : array.push({
[key]: [].concat(value)
});
return array;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(checkAndPush(ans, "c", [2,3]))
console.log(checkAndPush(ans, "c", 4));
Prototype function
Array.prototype.checkAndPush = function(key, value) {
var filteredList = this.filter(function(o) {
return Array.isArray(o[key]);
});
var dummy = {}
dummy[key] = [].concat(value)
filteredList.length > 0 ? filteredList[0][key].push(value) : this.push(dummy);
// or ES6: this.push({ [key]: [].concat(value) })
return this;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(ans.checkAndPush("c", [2,3]))
console.log(ans.checkAndPush("c", 4));
If you are dealing with objects as your values
ans[key] = ans[key] || []
ans[key].push(value)
Note, this works because your values will be an array. If they could be primatives then you would use hasOwnProperty to check.
if (ans.hasOwnProperty(key)) {
// Add this to your key somehow
} else {
// initialize the key with your value
}
Node.js is nothing but a library built on javascript. You can do anything using javascript type of progmming. However push and pop method should be able to help you to deal with nodejs array.
ans[key].push(value)

Find index of object in array by key

I have an array of objects like so
myobj= [{"item1" : info in here},{"item2" : info in here}, {"item3" : info in here}]
I'm trying to modify one, but I only know its key. I need to pinpoint the item1 object so I can change its value (the values are random and I don't know them, so I can't rely upon them).
If I could just get the index of the item it would be pretty easy: myobj[index].value = "newvalue".
Maybe using the index isn't the best way, so if it isn't, I'm open to other ideas.
I was thinking I could try something like
myobj.objectVar
Where objectVar is the key I'm being passed (item1, for example), however this does not work, possibly because it's a variable? Is it possible to use a variable like this maybe?
If it helps, I'm using underscore.js as well.
Your guess at a solution doesn't work because you're not accessing the individual objects, you're accessing an array of objects, each of which has a single property.
To use the data in the format you've got now, you need to iterate over the outer array until you find the object that contains the key you're after, and then modify its value.
myobj= [{"item1" : info in here},{"item2" : info in here}, {"item3" : info in here}]
function setByKey(key, value) {
myObj.forEach(function (obj) {
// only works if your object's values are truthy
if (obj[key]) {
obj[key] = value;
}
});
}
setByKey('item1', 'new value');
Of course, the far better solution is to stop using an array of single-property objects, and just use one object with multiple properties:
myobj= {"item1" : info in here, "item2" : info in here, "item3" : info in here};
Now, you can simply use myObject.item1 = "some new value" and it will work fine.
You can write a function like,
function getElementsHavingKey(key) {
var objectsHavingGivenKey = [];
//loop through all the objects in the array 'myobj'
myobj.forEach(function(individualObject) {
//you can use 'hasOwnProperty' method to find whether the provided key
// is present in the object or not
if(individualObject.hasOwnProperty(key)) {
// if the key is present, store the object having the key
// into the array (many objects may have same key in it)
objectsHavingGivenKey.push(individualObject);
}
});
// return the array containing the objects having the keys
return objectsHavingGivenKey;
}
If you only want to get the index of elements having the given key
You can do something like this,
function getIndexesOfElementsHavingKey(key) {
var objectsHavingGivenKey = [];
//loop through all the objects in the array 'myobj'
myobj.forEach(function(individualObject, index) {
//you can use 'hasOwnProperty' method to find whether the provided key
// is present in the object or not
if(individualObject.hasOwnProperty(key)) {
//push index of element which has the key
objectsHavingGivenKey.push(index);
}
});
// returns the array of element indexes which has the key
return objectsHavingGivenKey;
}
Try this code:
function changeObj( obj, key, newval )
{
for( var i=0, l=obj.length; i<j; i++)
{
if( key in obj[i] )
{
obj[i] = newval;
return;
}
}
}
var myObjArray= [{"item1" : "info in here"},{"item2" : "info in here"}, {"item3" : "info in here"}]
To find and add new value to the object inside an array:
myObjArray.forEach(function(obj) {
for(var key in obj) {
// in case you're matching key & value
if(key === "item1") {
obj[key] = "update value";
// you can even set new property as well
obj.newkey = "New value";
}
}
});
You can access objects the same using their index, even the object inside the original object.
Is this kind of what your looking for:
var otherObj = [{"oitem":"oValue"}];
var myobj= [{"item1" : otherObj},{"item2" : "2"}, {"item3" : "tesT"}];
myobj[0].item1[0].oitem = "newvalue";
alert(myobj[0].item1[0].oitem);

append values to array inside object based on key in JS

I have an object and want to append values to arrays inside it based on key.
For eg.
var A = {};
A[room1] = ["1"];
A[room2] = ["2"];
A[room3] = ["3"];
which will be looking like
A = {"room1":["1"], "room2":["2"], "room3":["3"]};
But what I want is that whenever a user gives some value corresponding to the already added key, instead of overwriting the previous value I want to append in it.
If, for example, value came as 101 and I want to add it to key room1 in such a way that later these values can be retrieved easily.
So the whole object this time becomes
A = {"room1":["1","101"], "room2":["2"], "room3":["3"]};
Now if I want to add 201 to key room2 , it will be:
A = {"room1":["1","101"], "room2":["2","201"], "room3":["3"]};
What I have I tried?
I have an array. I don't want to use many arrays.
var arr = [];
whenever value cam I push it to the array
arr.push(value);
But pushing it to the array leads to adding values to all not to the corresponding key
[[The first part of this answer is based on a previous version of the OP's question which has now been edited to a different problem. See the second part of this answer for the solution which applies to the current edit of the question (It really messes things up when the whole question gets changed to something else.]]
Original Answer
You just have to test if the key already exists and examine if there's already an array there. If the key doesn't exist, add it. If the key exists and it's already an array, just push another value into the array. If the key exists, but it's not an array, grab the value and then reset the key to an array with the first two values in it.
Here's code to do that:
function addValue(obj, key, value) {
if (obj.hasOwnProperty(key)) {
// check if it's already an array using the recommended way of detecting an array
if (Object.prototype.toString.call(obj[key]) === "[object Array]")
obj[key].push(value);
} else {
var firstVal = obj[key];
obj[key] = [firstVal, value];
}
} else {
obj[key] = value;
}
}
Latest Answer
FYI, your data structure choice is difficult to both read and write because both reader and writer have to check the type of a value before they can operate on it. It would be much easier if items were just always arrays with one or more elements in them like this.
// one item for each key
A = {"room1":["1"], "room2":["2"], "room3":["3"]};
// add 101 to room 1
A = {"room1":["1","101"], "room2:["2"], "room3":["3"]};
// add 201 to room 2
A = {"room1":["1","101"], "room2":["2","201"], "room3":["3"]};
Then, you would need any special code to read and to write, you'd just check if the key exists and if so, push a new value into it. If not, add the array.
In this case, adding a value would just be this
function addValue(obj, key, value) {
if (obj.hasOwnProperty(key)) {
obj[key].push(value);
} else {
obj[key] = [value];
}
}
try this
function pushValue(obj, key, value)
{
if(obj.hasOwnProperty(key) {
var currentVal = obj[key];
if(currentVal instanceof Array)
obj[key].push(value);
else
obj[key] = [currentVal, value];
} else {
alert("No such key.");
}
}
Your requirement can be achieved in this way too.
function pushValue(obj, key, value)
{
if(obj[key])
{
if(obj[key].push)
{
obj[key][obj[key].length] = value;
}
else
{
var xContainedVal = obj[key];
obj[key] =[xContainedVal, value];
}
}
else
{
alert("Key Not Found!");
}
}
Updated:
function pushValue(obj, key, value)
{
if(obj[key])
{
obj[key][obj[key].length] = value;
}
else
{
obj[key] =[value];
}
}
A working demo

Categories

Resources