how to generate a URL from JSON object? - javascript

UPDATE
Updated the JSON model
I have 2 JSON objects look like:
{
"scheme":"https",
"server":"example.com"
}
and
{
"scheme":"https",
"server":"example.com",
"path":"items",
"item":"apple",
"itemDetails":[
{
"country":"US",
"year":"2019"
}
]
}
I want to make them into URL such as
https://example.com or https://example.com/items?item=apple&country=US&year=2019
How can I do?

You could create a function which creates the URL based on the object provided.
Destructure the parameter to get scheme, server, path. Assign a default value to path since it is optional. Get the remaining unknown properties to a rest variable using spread syntax (Properties like item, itemDetails etc will be inside the rest object)
You can create the base URL using the first 3 variables using a template literal
To get the query string, you can use URLSearchParams constructor. It has several overloads. You can pass a query string or an object or an array of entries as parameter to the constructor. If the object is flat, you simply do, new URLSearchParams(rest).toString() to create the query string. But, since you have nested arrays and objects, we need to create an array of entries first (Something like: [[key1, value1], [key2, value2],...and so on]. Then the string will be key key1=value1&key2=value2. The values will also be properly encoded to replace space and special characters etc)
You can create a recursive function to get the nested entries. Loop through the entries of the given object. If the current value is an Array, recursively call the method for each object in the array and push it to entries. If the value is an object, recursively call the function on the value. This function will return a 2-dimensional array of all the key-value pairs in the object.
Then simply pass the entries to URLSearchParams to create the query string. If the query string is not empty, append it to the base URL with a prefix of ?.
function createURL({ scheme, server, path = '', ...rest }) {
let url = `${scheme}://${server}/${path}`;
let param = new URLSearchParams(getEntries(rest)).toString();
if (param)
url += "?" + param;
return url
}
function getEntries(o = {}) {
const entries = [];
for (const [k, v] of Object.entries(o)) {
if (Array.isArray(v))
entries.push(...v.flatMap(getEntries))
else if (typeof v === 'object')
entries.push(...getEntries(v))
else entries.push([k, v])
}
return entries;
}
console.log(createURL({
scheme: "https",
server: "example.com"
}))
console.log(createURL({
scheme: "https",
server: "example.com",
path: "items",
item: "apple",
"itemDetails": [{
"country": "US",
"year": "2019"
}]
}))

Maybe is not the best way, but you can try
var myjson = {
scheme:https,
server:example.com
};
var obj = JSON.parse(myjson);
document.getElementById("#div1").innerHTML = obj.scheme + obj.server;

Related

Search into a json file a value with only javascript and fs

i want to create a javascript function for search into a json file a object with the value.
getByValue(value) {
//the code
}
When i call the function, i need to search into a json file (the path is "./database/table.json") what i passed with value parameter, and return the object name.
An example:
JSON file:
{"name": "test"}
getByValue(value) {
//code for search into the file
}
//search on the json file a object value with "test"
console.log(getByValue("test"))
//expected output: "name"
You can do something like this :
const json = { "name": "test" , "name1" : "test1"}
const getByValue = value => {
for (let key of Object.keys(json)) if (json[key] === value) return key;
}
//search on the json file a object value with "test"
console.log(getByValue("test"))
//expected output: "name"
You need to first load that JSON in JS environment and parse it to read. In node.js you can do something like this
const jsonFromFile = require('filepath/file.json')
After reading the JSON, you just need to find the key where the value is given. There are multiple approaches to this. The basic solution is need to iterate over the object and find the value which matches.
One such approach:
const findKeyBasedOnValue = (obj, value) => Object.keys(obj).find((key) => obj[key] === value)
const data = {a: 'no-test', b: 'test'}
console.log(findKeyBasedOnValue(data, 'test')) // b

Javascript: How to push key:pair values in Javascript Object which is already created

My question Explanation:
I have a variable of type = new FormData()
It has some key pair values for example.
const _CheckOutData = new FormData(); // Creating FormData object to send mulitpart data
_CheckOutData.append('Name', this._CheckOutForm.get('name').value);//Appending values to the
_CheckOutForm varibale from FormGroup
_CheckOutData.append('Street', this._CheckOutForm.get('street').value);//Appending values to the
_CheckOutForm varibale from FormGroup
_CheckOutData.append('City', this._CheckOutForm.get('city').value);/
I want to save these values in localStorages. when I directly save _ChechOutData to local storage its empty. Snippet of this function is
SaveFormDataToLocalStorage(_CheckOutData){
localStorage.setItem('_CheckOutData',JSON.stringify(_CheckOutData));
}
So getting empty local Storage. I tried a different apporach which actually work but as my Question is I want to push the values from the _CheckOutData (Type FormData) into new object. here is the snippet
_CheckOutData.forEach((key,value)=>{
let Value=key;
let Key=value;
let TemporaryCart={
[Key]:Value
}
this._CartCheckOutData.push(TemporaryCart);
})
So I am Successfully getting all and values and save them into TemporaryCart (type Object). But the Problem is if there are 5 values it is created 5 object in the Array.But I want to creat one Object with 5 values in it.
My Actual Result:
[{Name: "Fazi"}, {Street: "10570 S De Anza Blvd, Cupertino, CA 95014, United States"}]
But What I want
[
{
Name:"Fazi",
Street:"xyz 123",
.
.
.
.
And So One
}
]
Please Help me community: Regards Abdul Rehman
Hi you can try this one to change formdata in object
formData.forEach(function(value, key){
object[key] = value;
});
var json = JSON.stringify(object);
I would try to set the keys of the object this way:
some_list = []
some_object = {}
some_object['new_key_1']=123
some_object['new_key_2']='abc'
some_object
some_list.push(some_object)
will give you
> some_object
{ new_key_1: 123, new_key_2: 'abc' }
> some_list
[ { new_key_1: 123, new_key_2: 'abc' } ]
Because you want to copy one object into another you could also try alternatively:
> target_object = {...some_object, and_another_key:'123.123'}
{ new_key_1: 123, new_key_2: 'abc', and_another_key: '123.123' }
good luck!
A FormData object will look more like an array of arrays than an actual object. That's basically why a FormData object can have more entries with the same key.
So instead of trying to convert the FormData into an object into JSON, try to turn in into an array.
const formDataToJSON = formData => {
const entriesArray = [...formData];
return JSON.stringify(entriesArray);
}
This will first turn the FormData object into an array that looks like this (before the JSON step):
[
["Name", "Fazi"],
["Street", "xyz 123"],
]
This format will keep all the values in the FormData intact, as you could have multiple keys with the same name.
Reversing the process can be done as well.
const JSONtoFormData = json => {
const formData = new FormData();
const entriesArray = JSON.parse(json);
for (const [name, value] of entriesArray) {
formData.append(name, value);
}
return formData;
};

How to avoid "Arrow function expect to return a value" error in Airbnb ESLint

I am running eslint and it is recommended to return a value whenever an arrow function(lambda function) is used. Well that makes sense. However, I come across a case that is hard to walk around.
Dict = {}
Instances = [/* an array of items where items is a dictionary that contains data */]
Instances.map((item) => {
Dict[item.name] = item.url;
});
My goal is to get the data from the Instances array and fill the dictionary Dict with it. I am using the array function to assign key value pair to the dictionary, but that violates the rule of the arrow function.
Is there any iteratools or functions other than map that would help me to achieve the goal, and avoid the rule violation?
Edit: This does not adhere to Airbnb's ES6 Style Guide.
My goal is to get the data from the Instances array and fill the dictionary with it.
Use .reduce
.. and just pass an empty object as the accumulator, filling it up as you iterate through your array.
const instances = [
{ name: 'foo', url: 'https://google.com' },
{ name: 'bar', url: 'https://stackoverflow.com' }
]
const result = instances.reduce((dict, item) => {
dict[item.name] = item.url
return dict
}, {})
console.log(result)
Why not .map?
Array.map always returns a new Array and is meant for mapping each array element to another format.
If your resulting data structure shouldn't be an Array, with the same length as the Array you are operating on, you should avoid using it.
Why .reduce instead of .forEach?
I use forEach only for doing "work" rather than transforming data. Transforming data is almost always achievable with just map and/or reduce.
Here's what I mean by "work":
const users = [userInstance, userInstance, userInstance]
users.forEach(user => user.sendEmail('Hello World'))
Use forEach instead of map.
The point of map is to modify each item in an array and put the modified versions in a new array.
forEach just runs a function on each item.
If you are looking for ES6 solution to fill dictionary object this could help and should pass ESLint also:-
const dict = Instances.reduce((map, obj) => (map[obj.name] = obj.url, map), {});
update
const dict = Instances.reduce((map, obj) => {
let mapClone = {};
mapClone = Object.assign({}, map);
mapClone[obj.name] = obj.url;
return mapClone;
}, {});

observable to return many json objects from server will contain all at once or iterate through?

I'm using angular 4 and typescript
I have created an api endpoint that will return a array of json objects. My question refers to capturing the json inside a variable designed to hold an array of javascript objects. Will the observable return a list of json objects to where I can just set the variable in my typescript code to that array? And if so how.
Or do I have to iterate through the list of json objects and append them to the array variable?
Notice no code, as I am confused as to when I use interaces, when I use constructors and the alike. I would like to see how this is done. I am still learning
getData(): Observable<Array<any>> {
return this.http.get("http://apiurl")
.map((response: Response) => response.json());
}
Set Observable type to Array<any>,
you can replace any with your datatype.
Iterate over an array using
let list = [{"name": "john"}, {"name": "doe"}];
for (let i in list) {
console.log(i); // indexes will be printed
}
for (let i of list) {
console.log(i); // Actual values will be printed
}
Service :
getData(): Observable<any> {
return this.http.get(`yourUrl`)
.map(r => r.json());
}
Component :
yourFunction() {
this.service.getData().subscribe(
data => {
// If your API returns an Array, then data is an array.
// If it returns one line, then it's an object.
}
);
}

Convert array of javascript objects to JSON

I have a set of data in the format:
[{"title":movietitle1, "id":445, "release":"16JUN1985"}, {"title":movietitle2, "id":487, "release":"12AUG1993"}]
Which I need to convert into JSON formatted as such:
{
"movietitle1":{"id":445,"release":"16JUN1985"},
"movietitle2":{"id":487, "release":"12AUG1993"}
}
I don't have any idea of how to make this happen.
You can do this with JSON.stringify() and some basic data manipulation.
Store your data in a variable, lets call it input_data.
Loop through your data and use each entry to build up another variable, lets call it output_data.
// create an object to store the newly formatted data
var output_data = {};
// the code in here is run once for each item in input_data
for (var i = 0; i < input_data.length; i++) {
// get the current item's title
var title = input_data[i].title;
// use the title as the key in the output data
// and assign the other values to that key
output_data[title] = {
id: input_data[i].id,
release: input_data[i].release
};
}
// use JSON.stringify() to make a valid JSON string
var json = JSON.stringify(output_data);
// now use the variable json which contains your JSON string
What you are asking for is to turn an array into a map , keying by a specific property, If you really want JSON, you can just call JSON.stringify on the resulting JS object.
http://jsfiddle.net/FfE8f/1/
/**
* Given an array and a property name to key by, returns a map that is keyed by each array element's chosen property
* This method supports nested lists
* Sample input: list = [{a: 1, b:2}, {a:5, b:7}, [{a:8, b:6}, {a:7, b:7}]]; prop = 'a'
* Sample output: {'1': {a: 1, b:2}, '5': {a:5, b:7}, '8': {a:8, b:6}, '7':{a:7, b:7}}
* #param {object[]} list of objects to be transformed into a keyed object
* #param {string} keyByProp The name of the property to key by
* #return {object} Map keyed by the given property's values
*/
function mapFromArray (list , keyByProp) {
var map = {};
for (var i=0, item; item = list[i]; i++) {
if (item instanceof Array) {
// Ext.apply just copies all properties from one object to another,
// you'll have to use something else. this is only required to support nested arrays.
Ext.apply(map, mapFromArray(item, keyByProp));
} else {
map[item[keyByProp]] = item;
}
}
return map;
};
console.log(mapFromArray([
{"title": "title 1", "id":445, "release":"16JUN1985"},
{"title":"movietitle2", "id":487, "release":"12AUG1993"}],
"title"
)));
// outputs
{
"title 1": {"title":"title 1","id":445,"release":"16JUN1985"},
"movietitle2": {"title":"movietitle2","id":487,"release":"12AUG1993"}
}
See More efficient way to search an array of javascript objects?
Your mixing terms. I'm assuming you're asking about manipulating data with JavaScript objects and not strings with JSON data. (The later can be converted with JSON.parse).
First iterate over the array and assigning to an object. This kind of data manipulation works well using Underscore, check it out.
In vanilla JS lets try something like this:
var newData = {};
data.forEach(function(item) {
var title = item.title;
delete item.title;
newData[title] = item;
});
A little crufty but gets the job done.
Personally I'd use this Underscore version:
var newData = _(data).chain()
.map(function(item) {
return [item.title, _(item).omit('title')];
})
.object()
.value();

Categories

Resources