How do I Save JSON API response in different javascript arrays - javascript

Working on API response that gets user data from 10K ft system via API. The response looks like:
"data": [{
"id": 30000,
"display_name": "John Doe",
"email": "Johndoes#testmail.com",
},
I want to save this data in three different arrays for each response to be used later for looping through user id. I am not sure how to go about it. Below is the code I have worked on so far. I will appreciate any help here. Thanks
function getUsers() {
var auth = 'authentication'
var url = 'https://api.10000ft.com/api/v1/users?' + '&auth=' + auth;
var options = {
method: 'get',
headers: {
Authorization: 'Bearer ' + auth
}
};
};
let response = UrlFetchApp.fetch(url, options);
let json = JSON.parse(response);
};
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response);
var ids = [];
var display_names = [];
var emails = [];
function result(data) {
data.forEach(element => {
ids.push(element.id);
display_names.push(element.display_name);
emails.push(element.email);
});
return { "ids": ids, "display-names": display_names, "emails": emails };
}
console.log(result(data));

From what I understand...Maybe you're looking for something like this?
let json = JSON.parse(response);
let ids = [];
let dis_name = [];
let email = [];
for(let i = 0; i < json.length; i++){
ids.push(json[i].id);
dis_name.push(json[i].display_name);
email.push(json[i].email);
}
P.S Consider using let keyword instead of var.

if "data" contains more objects you need to loop through the data array and push the ids, display_names and emails in separate arrays. The below example will help you.
var data = [
{
"id": 30000,
"display_name": "John Doe",
"email": "Johndoes#testmail.com"
},
{
"id": 30001,
"display_name": "John Cena",
"email": "JohnCens#testmail.com"
},
{
"id": 30002,
"display_name": "John kabaraya",
"email": "Johnkabarayas#testmail.com"
}
]
var ids = [];
var display_names = [];
var emails = [];
function result(data) {
data.forEach(element => {
ids.push(element.id);
display_names.push(element.display_name);
emails.push(element.email);
});
return { "ids": ids, "display-names": display_names, "emails": emails };
}
console.log(result(data));

Related

How can I download a single merged JSON file within a loop whilst using Google API and Javascript?

I have a script that is looping through an array of Google Place IDs and returns some of their Place Details. I’m then using JSON.Stringify to output the data in JSON format.
function initMap() {
//====Array of Google Place IDs=====//
var placeid_list = [{
"placeid": 'ChIJryijc9s0K4gRG9aU7SDTXdA',
}, {
"placeid": 'ChIJaZ6Hg4iAhYARxTsHnDFJ9zE',
}, {
"placeid": 'ChIJl64IQXrYzUwR8CVOTRf_h3o',
}, {
"placeid": 'ChIJBTMkuph-zkwR9oEF8Nv3Z0o',
}, {
"placeid": 'ChIJ4QbSBj8IzkwRGi0ILu03_VA',
}, {
"placeid": 'ChIJc2nSALkEdkgRkuoJJBfzkUI',
}, {
"placeid": 'ChIJmzrzi9Y0K4gRgXUc3sTY7RU',
}];
function setPlaces() {
var json = placeid_list;
//====Loop for Place IDs=====//
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i];
createPlace(data);
}
}
function createPlace(data) {
var service = new google.maps.places.PlacesService(document.getElementById("placeResults"));
console.log(data);
service.getDetails({
placeId: data.placeid,
fields: [
"name",
"formatted_address",
"place_id",
"geometry",
"type",
"formatted_phone_number",
"rating",
"reviews",
"website",
"url",
"photos",
"opening_hours",
"price_level"],
}, function (result, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
placeResults(data, result);
});
}
function placeResults(data, result) {
//====Merge Data from each of looped Place IDs=====//
const mergedObj = Object.assign(result);
const jsonStr = JSON.stringify(mergedObj, 0, 2);
const jsonFile = document.getElementById("placeResults").textContent += jsonStr;
//====Output JSON data in JSON File=====//
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([jsonFile], {
type: "application/json"
}));
a.setAttribute("download", "data.json");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
//====Output JSON data in text format=====//
//document.getElementById("placeResults").textContent += jsonStr;
}
setPlaces();
}
window.initMap = initMap;
I’m trying to make it so that the combined JSON details for each place can be downloaded as a single file. Currently, the code above is generating 7 separate file downloads (the same amount of place IDs I have). Each of these files contains data for all of the Place IDs. But I only need 1 of these files.
I have been able to combine the data from each of the 7 place IDs and display it using the following:
const mergedObj = Object.assign(result);
const jsonStr = JSON.stringify(mergedObj, 0, 2);
const jsonFile = document.getElementById("placeResults").textContent += jsonStr;
//====Output JSON data in text format=====//
//document.getElementById("placeResults").textContent += jsonStr;
To generate a downloadable JSON file containing the place details, I'm using this:
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([jsonFile], {
type: "application/json"
}));
a.setAttribute("download", "data.json");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
I'm hoping someone can help me in getting just 1 file to download when the script runs. Ideally, the process if to loop through all the place IDs, output their data in JSON format, merge it all, then download a single file containing everything.
Any help is very much appreciated.
You have asynchronous calls to the Google PlacesService(), where the responses come back in an unpredictable order and timing. In order to collect the responses you could either use promises, or a counter that keeps track of the calls and returns.
Here is your code modified using a counter. The code is untested since I don't have all the details.
Some notes:
the createPlace() function has a callback, which is called on success and failure
a count variable gets incremented before calling createPlace(), and decremented in the callback function
the callback function adds the result to the resultArray variable
all calls are done once the counter reaches 0 in the callback function, at which point to call placeResults()
function initMap() {
//====Array of Google Place IDs=====//
var placeid_list = [
{ "placeid": 'ChIJryijc9s0K4gRG9aU7SDTXdA' },
{ "placeid": 'ChIJaZ6Hg4iAhYARxTsHnDFJ9zE' },
{ "placeid": 'ChIJl64IQXrYzUwR8CVOTRf_h3o' },
{ "placeid": 'ChIJBTMkuph-zkwR9oEF8Nv3Z0o' },
{ "placeid": 'ChIJ4QbSBj8IzkwRGi0ILu03_VA' },
{ "placeid": 'ChIJc2nSALkEdkgRkuoJJBfzkUI' },
{ "placeid": 'ChIJmzrzi9Y0K4gRgXUc3sTY7RU',}
];
function setPlaces() {
let resultArray = [];
let callCount = 0;
placeid_list.forEach(data => {
callCount++;
createPlace(data, function(result) {
callCount--;
if(result) {
resultArray.push(result);
}
if(!callCount) {
// all async calls done
placeResults(resultArray);
}
});
});
}
function createPlace(data, callback) {
var service = new google.maps.places.PlacesService(document.getElementById("placeResults"));
console.log(data);
service.getDetails({
placeId: data.placeid,
fields: [ "name", "formatted_address", "place_id", "geometry", "type", "formatted_phone_number", "rating", "reviews", "website", "url", "photos", "opening_hours", "price_level" ],
}, function (result, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
callback();
return;
}
callback(result);
});
}
function placeResults(resultArray) {
const mergedObj = Object.assign(resultArray);
const jsonStr = JSON.stringify(mergedObj, 0, 2);
const jsonFile = document.getElementById("placeResults").textContent += jsonStr;
//====Output JSON data in JSON File=====//
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([jsonFile], {
type: "application/json"
}));
a.setAttribute("download", "data.json");
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
setPlaces();
}
window.initMap = initMap;

showing only the first value

I have this emails from an api response
"emails": "{\"1\": \"help#me.com\", \"2\": \"help2#help.com\", \"3\": \"please#helpme.com\"}"
I tried to push it into an array like
this.data.forEach((item) => {
dataArr.push([
Object.values(JSON.parse(item.emails)),
])
})
But I'm getting only the first email and not the other emails. how do I solve this problem?
Use concat, not push Copy array items into another array
this.data.forEach((item) => {
dataArr = dataArr.concat(
Object.values(JSON.parse(item.emails))
)
})
Assuming you got a JSON object :
obj = {
"emails": "{\"1\": \"help#me.com\", \"2\": \"help2#help.com\", \"3\": \"please#helpme.com\"}"
}
You can parse it to a real emails object then for each field add it in an array :
let emails = [];
const jsonemails = JSON.parse(obj.emails);
for (let field in jsonemails)
emails.push(jsonemails[field]);
This adds each email to the array:
const data = {
item1: {
"id": 1111111,
"emails": "{\"1\": \"help#me.com\", \"2\": \"help2#help.com\", \"3\": \"please#helpme.com\"}",
"name": "John Doe"
},
item2: {
"id": 2222222,
"emails": "{\"1\": \"help#me.com\", \"2\": \"help2#help.com\", \"3\": \"please#helpme.com\"}",
"name": "Jane Doe"
}
}
let dataArr = []
let emailArr = []
for (const item in data) {
const value = data[item]
const parsedEmails = JSON.parse(value.emails)
for (const email in parsedEmails) {
emailArr.push(parsedEmails[email])
}
dataArr.push([value.id, emailArr, value.name])
emailArr = []
}
console.log(dataArr)
Parse the response first, then use the Object.keys function.
let string = <Api Response>;
let parsed = JSON.parse(string);
let emails = Object.values(parsed.emails);
// your raw data (in your case, 'this.data')
const data = JSON.stringify({
"emails":{
"1":"help#me.com",
"2":"help2#help.com",
"3":"please#helpme.com",
"11":"please11#helpme.com"
}
});
// 1. Parse the response
const parsedData = JSON.parse(data); // in your case 'JSON.parse(this.data);'
// 2. create the array of emails
const emailsArr = Object.values(parsedData.emails);
// 3. loop through the array
emailsArr.forEach(email => {
console.log(email);
});

API Call Before Next Iteration Starts in Loop

I would like to send a POST request to a certain app through their API. What I am trying to do is to process the input data (called data) and send a POST request on one record by one record in the loop. Then, I delete the corresponding object in data for optimization purpose. I know that because of the asynchronous feature of JavaScript, the loop finishes before the function gets called. However, even though I wrap the api function in IIFE or wrap it in an async function with await(the code is below), the compiler still gives me function calls with the same parameter which is the last object. So, when I see created records on the app, David's information was generated three times. The screenshot below is each record object after being processed. If you could tell me ways of triggering the api call before the next iteration in the loop, that would be greatly appreciated.
const obj = [];
var record = {};
var data = [
{
"userId": "123",
"name": "John",
"phoneNumber": "123-456-6789"
},
{
"userId": "345",
"name": "Summer",
"phoneNumber": "535-631-9742"
},
{
"userId" : "789",
"name": "David",
"phoneNumber": "633-753-1352"
}
]
var dataLen = data.length;
var people = data;
createKeyValue = ((key, value) => {
var temp = {};
temp["value"] = value;
obj[key] = temp;
});
apiCall = ((record) => {
clientInformation.record.addRecord.then((resp) => {
console.log(resp);
}).catch((err) => {
console.log(err);
});
});
async function asyncFunction(record) {
let promise = new Promise((resolve, reject) => {
setTimeout(() => apiCall(record), 1000)
});
let result = await promise;
console.log(result);
}
while (dataLen > 0) {
for (let [key, value] of Object.entries(data[0])) {
switch(key) {
case 'userId':
createKeyValue(key, value);
break;
case 'name':
createKeyValue(key, value);
break;
default:
}
}
record["record"] = obj;
asyncFunction(record);
data.shift();
dataLen -= 1;
}
Here is the screenshot of how each processed data looks like.
I think you haven't understand how the for loop inside the while works. The data should be incremented each time to get the next array inside data.
The data[0] => { userId: 123 ... }, data[1] => { userId: 345 ... } and so on .
At each for loop iteration checks the 3 elements of each sub array, so each time temp stores the key values for userId and name. So when the loop finishes, the temp contains as key => userId, name and the corresponding values.
var data = [
{
"userId": "123",
"name": "John",
"phoneNumber": "123-456-6789"
},
{
"userId": "345",
"name": "Summer",
"phoneNumber": "535-631-9742"
},
{
"userId" : "789",
"name": "David",
"phoneNumber": "633-753-1352"
}
]
var dataLen = data.length;
let i = 0 ;
while ( i < dataLen) {
let temp = [];
for (let [key, value] of Object.entries(data[i])) {
if(key == 'userId' || key == 'name'){
temp[key] = value;
}
}
//Just to print the values and understand
for(let k in temp){
console.log(k+" -> "+temp[k]);
}
//here you will pass the temp values to functions
console.log(" At each iteration execute the required functions ");
//asyncFunction(temp);
i += 1;
}

Javascript push array inside object

How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);

How to replace old json object with a new one with NodeJS

How to replace old json object using NodeJS with a new updated object ?
Right now when i update the json file it saves the new data with the old one.
JSON :
[ {
"id": 1,
"name": "Sven",
"phone": "123123"
},
{
"id": 2,
"name": "Martin",
"phone": "2342342"
} ]
Here is my code :
var operation = POST.operation; // POST request comes with operation = update/insert/delete
if (operation == 'update') {
fs.readFile("file.json", "utf8", function (err, data) {
var jsonFileArr = [];
jsonFileArr = JSON.parse(data); //Parse the data from JSON file
var haveId = jsonFileArr.some(function (obj){ // Checks if the POST request have the same id as JSON file
return obj.id == POST.id;
})
if (haveId) { // if true
var updateData = []; // Array with POST data
updateData.push({
id: POST.id,
name: POST.name,
phone: POST.phone,
})
jsonFileArr.push(updateData);
var newUsers = JSON.stringify(jsonFileArr);
fs.writeFile("file.json", newUsers, "utf8");
console.log(err);
}
})
}
I should probably use delete object but how can i specify what object should be removed ?
So when i update data with id 1 it would delete the old id / Name / phone and write the new data.
My assumption base on your question is that you have multiple objects in one file. So the easy way to work around this would be to
if (operation == 'update') {
fs.readFile("file.json", "utf8", function (err, data) {
var jsonFileArr = [];
jsonFileArr = JSON.parse(data); //Parse the data from JSON file
var haveId = jsonFileArr.some(function (obj){ // Checks if the POST request have the same id as JSON file
return obj.id == POST.id;
})
if (haveId) { // if true
var updateData = []; // Array with POST data
updateData.push({
id: POST.id,
name: POST.name,
phone: POST.phone,
})
for(let Arr of jsonFileArr){
if (Arr.id == POST.id){
let currentIndex = jsonFileArr.indexOf(Arr);
jsonFileArr.splice(currentIndex,1,updateData) //removing the old object and adding the new one
}
}
var newUsers = JSON.stringify(jsonFileArr);
fs.writeFile("file.json", '', "utf8",function(err,res){ //Making the file empty
if(!err){
fs.writeFile("file.json", newUsers, "utf8",function(err,res){ //Writing the whole object back
if(err)console.log(err);
console.info(res);
});
}else{
console.log(err);
}
});
}
})
}
I think this is better instead of using some, get the matching index and replace directly.
var jsonFileArr = JSON.parse(data); //Parse the data from JSON file
var foundId = jsonFileArr.findIndex(function (obj){ // Checks if the POST request have the same id as JSON file
return obj.id == POST.id;
});
if (foundId >= 0) {
jsonFileArr[foundId] =
{
id: POST.id,
name: POST.name,
phone: POST.phone,
}
}
.... and then write back to file

Categories

Resources