Below is the response from Paypal's NVP API. I am not familiar with working with a response that is a single object of keys/values like this. Typically I would expect for a search to be return in a form of an array with objects within.
Is there a way for me to turn this into an Array of Objects?
{
L_TIMESTAMP0: "2018-05-08T19:23:17Z",
L_TIMESTAMP1: "2018-05-08T18:50:01Z",
L_TIMESTAMP2: "2018-05-08T18:45:30Z",
L_TIMEZONE0: "GMT",
L_TIMEZONE1: "GMT",
L_TIMEZONE2: "GMT",
L_TYPE0: "Payment",
L_TYPE1: "Payment",
L_TYPE2: "Payment",
L_NAME0: "Person One",
L_NAME1: "Person Two",
L_NAME2: "Person Three",
L_TRANSACTIONID0: "*********",
L_TRANSACTIONID1: "*********",
L_TRANSACTIONID2: "*********",
L_STATUS0: "Completed",
L_STATUS1: "Completed",
L_STATUS2: "Completed",
L_AMT0: "10.00",
L_AMT1: "100.00",
L_AMT2: "1000.00",
L_CURRENCYCODE0: "USD",
L_CURRENCYCODE1: "USD",
L_CURRENCYCODE2: "USD",
L_FEEAMT0: "-0.29",
L_FEEAMT1: "-2.93",
L_FEEAMT2: "-29.30",
L_NETAMT0: "9.71",
L_NETAMT1: "97.70",
L_NETAMT2: "970.70",
TIMESTAMP: "2018-05-08T19:47:10Z", // not for array
CORRELATIONID: "*******", // not for array
ACK: "Success", // not for array
VERSION: "204", // not for array
BUILD: "39949200" // not for array
}
I would like parse this into an array of objects:
const recentOrders = [{
timestamp: L_TIMESTAMP0,
timezone: L_TIMEZONE0,
type: L_TYPE,
.....
},
{ timestamp: L_TIMESTAMP1, .... },
{ timestamp: L_TIMESTAMP2, .... },
// .... and so forth
]
Something like this should work:
var data = {
L_TIMESTAMP0: "2018-05-08T19:23:17Z",
L_TIMESTAMP1: "2018-05-08T18:50:01Z",
L_TIMESTAMP2: "2018-05-08T18:45:30Z",
L_TIMEZONE0: "GMT",
L_TIMEZONE1: "GMT",
L_TIMEZONE2: "GMT",
L_TYPE0: "Payment",
L_TYPE1: "Payment",
L_TYPE2: "Payment",
L_NAME0: "Person One",
L_NAME1: "Person Two",
L_NAME2: "Person Three",
L_TRANSACTIONID0: "*********",
L_TRANSACTIONID1: "*********",
L_TRANSACTIONID2: "*********",
L_STATUS0: "Completed",
L_STATUS1: "Completed",
L_STATUS2: "Completed",
L_AMT0: "10.00",
L_AMT1: "100.00",
L_AMT2: "1000.00",
L_CURRENCYCODE0: "USD",
L_CURRENCYCODE1: "USD",
L_CURRENCYCODE2: "USD",
L_FEEAMT0: "-0.29",
L_FEEAMT1: "-2.93",
L_FEEAMT2: "-29.30",
L_NETAMT0: "9.71",
L_NETAMT1: "97.70",
L_NETAMT2: "970.70",
TIMESTAMP: "2018-05-08T19:47:10Z", // not for array
CORRELATIONID: "*******", // not for array
ACK: "Success", // not for array
VERSION: "204", // not for array
BUILD: "39949200" // not for array
};
const recentOrders = [];
var keys = Object.keys(data).filter(r => r.startsWith('L_'));
keys.forEach(k => {
var index = parseInt(k.replace(/\D/g,''));
var newKey = k.substring(2).replace(/[0-9]/g, '').toLowerCase();
if (recentOrders[index] === undefined) {
recentOrders[index] = {};
}
recentOrders[index][newKey] = data[k];
});
console.log(recentOrders);
I'm not entirely sure what the output you want is, but fundamentally you want to map and transform the data from the very flat structure you are given to more of a list of related objects.
You can do this using some of the basic native methods of arrays to filter map and reorganize your data. The following code basically does the following:
Get the keys of the object
Filter the keys to the numbered ones you want
Map the keys to a small informational object about each
Reorganize the list of keys into a list of objects with the original indexed data in the objects at the correct index.
This can be done in one line with the end result being a a recentOrders variable set to an array of 3 objects with the named keys lowercased (which I think is what you are after)
const recentOrders = Object.keys(data)
.filter(function (key) {
return key.startsWith('L_')
})
.map(function (key) {
const parts = key.match(/^L_([A-Z]+)(\d+)$/);
return {
key: parts[1].toLowerCase(),
value: data[key],
index: parseInt(parts[2])
};
})
.reduce(function (recentOrders, item) {
if (recentOrders[item.index] == null) {
recentOrders[item.index] = {}
}
recentOrders[item.index][item.key] = item.value;
return recentOrders ;
}, []);
console.log(recentOrders);
Related
I am fetching data from an api that, sometimes, gives me multiple objects with the same values, or very similar values, which I want to remove.
For example, I might get back:
[
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
]
So I want to check that no two objects have a key with the same "Language" value (in this case, "English").
I would like to get the general process of filtering out the entire object if it's "Language" value is duplicated, with the extra issue of not having the same number of objects returned each time. So, allowing for dynamic number of objects in the array.
There is an example here:
Unexpeected result when filtering one object array against two other object arrays
but it's assuming that you have a set number of objects in the array and you are only comparing the contents of those same objects each time.
I would be looking for a way to compare
arrayName[eachObject].Language === "English"
and keep one of the objects but any others (an unknown number of objects) should be filtered out, most probably using .filter() method along with .map().
The below snippets stores the languages that have been encountered in an array. If the current objects language is in the array then it is filtered out. It makes the assumption that the first object encountered with the language is stored.
const objs = [
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
],
presentLanguages = [];
let languageIsNotPresent;
const objsFilteredByLanguage = objs.filter(function (o) {
languageIsNotPresent = presentLanguages.indexOf(o.Language) == -1;
presentLanguages.push(o.Language);
return languageIsNotPresent;
});
console.log(objsFilteredByLanguage);
You could take a hash table and filter the array by checking Name and Language.
var array = [{ Name: "blah", Date: "1992-02-18T00:00:00.000Z", Language: "English" }, { Name: "blahzay", Date: "1998-02-18T00:00:00.000Z", Language: "French" }, { Name: "blah", Date: "1999-02-18T00:00:00.000Z", Language: "English" }],
hash = {},
result = array.filter(({ Name, Language }) => {
var key = `${Name}|${Language}`;
if (!hash[key]) return hash[key] = true;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using Set makes it easy to remove duplicates for as many keys as you like. I tried to be as verbose as possible so that each step was clear.
var objects = [{ "Name": "blah", "Date": "1992-02-18T00:00:00.000Z", "Language": "English", }, { "Name": "blah", "Date": "1998-02-18T00:00:00.000Z", "Language": "French", }, { "Name": "blah", "Date": "1999-02-18T00:00:00.000Z", "Language": "English" }];
function uniqueKeyVals(objects, key) {
const objVals = objects.map(object => object[key]); // ex. ["English", "French", "English"]
return objects.slice(0, new Set(objVals).size); // ex. { "English", "French" }.size = 2
}
function removeKeyDuplicates(objects, keys) {
keys.forEach(key => objects = uniqueKeyVals(objects, key));
return objects;
}
// can also use uniqueKeyVals(key) directly for just one key
console.log("Unique 'Language': \n", removeKeyDuplicates(objects, ["Language"]));
console.log("Unique ['Language', 'Name']: \n", removeKeyDuplicates(objects, ["Language", "Name"]));
I would use the underscore module for JavaScript and the unique function in this scenario. Here is a sample array of data objects:
let data = [{
name: 'blah',
date: Date.now(),
language: "en"
},
{
name: 'noblah',
date: Date.now(),
language: 'es'
},
{
name: 'blah',
date: Date.now(),
language: 'en'
}];
Then we can use the unique function in the underscore library to only return a copy of the data that has unique values associated with the language key:
const result = _.unique(data, 'language');
I have an array like this:
[
{
"id": 10002,
"flag": false,
"list": [
"aaa",
"bbb"
]
},
{
"id": 10001,
"flag": true,
"list": [
"10002",
"10003"
]
},
{
"id": 10003,
"flag": false,
"list": [
"ccc",
"ddd"
]
}
]
i tried this
initially i have "10001" value so iterate this array to take "list" array if flag==true then stored into newarray. but its not working.
I want it to be like this: [ "aaa", "bbb", "ccc", "ddd" ].
If i understand correctly this is what you want:
const someArray = [
{
"id": 10001,
"list": [
"10002",
"10003"
]
},
{
"id": 10002,
"list": [
"aaa",
"bbb"
]
},
{
"id": 10003,
"list": [
"ccc",
"ddd"
]
}
];
const [head,...rest] = someArray;
const result = head.list.reduce((acc,currentId)=>acc.concat(rest.find(({id})=> id === parseInt(currentId)).list),[]);
Here is a jsFiddle https://jsfiddle.net/sudakatux/9hju85mt/22/
Explanation:
take the head and splitted from the rest since the head contains the ids.
using the head as a dictionary find each list for each id in the head and concatenate
note the id must be in the subsequent list else it will fail with undefined. if you want to account for this error you can set a defualt empty object with a list. for example this part:
rest.find(({id})=> id === parseInt(currentId)).list
Will look like
rest.find(({id})=> id === parseInt(currentId)) || {list:[]}).list
Which basically means if its undefined return an object that has an empty list so then it will concatenate an empty list which results in being the same list. (like multiplying by 1 in a multiplication)
Hope it helps.
EDIT after your edit.
If your array is in different order you need to find the dictonary and then the logic is the same
const [newHead] = otherArray.filter(({list}) => list.every(elem=>!isNaN(elem)));
const result2 = newHead.list.reduce(
(acc,currentId) =>acc.concat(otherArray.find(({id})=> id === parseInt(currentId)).list),[]);
if you are testing for the flag then your head filter would look like. the blocks are the same the only thing that changes is the condition.
const [newHead] = otherArray.filter(({flag}) => flag));
(note* that instead of using the rest i used the complete array(otherArray). since im targeting equality.
Im using filter and extracting the first element of the result. because im accounting for the possibility that in the future you may have more than one "dictionary element". if thats the case in the future then you just have to concat the lists from the filter result
const array = [
{
id: 10001,
flag: true,
list: ["10002", "10003"]
},
{
flag: false,
id: 10002,
list: ["aaa", "bbb"]
},
{
flag: false,
id: 10003,
list: ["ccc", "ddd"]
}
];
const isHead = item => item.flag && item.id === 10001;
const head = array.find(isHead);
const rest = array.filter(item => !isHead(item));
const result = rest
.flatMap(item =>
head.list.includes(item.id.toString()) && item.list
);
console.log(result);
You can map over the list of the first item and concat all the lists from those ids.
const mapItems = (input) => {
const source = input[0].list;
source.reduce((results, id) => {
return results.concat(input.find(item => item.id === id).list);
}, []);
};
mapItems([
{
"id": 10001,
"list": [
"10002",
"10003"
]
},
{
"id": 10002,
"list": [
"aaa",
"bbb"
]
},
{
"id": 10003,
"list": [
"ccc",
"ddd"
]
}
]);
You can fetch the values of the list of first object in the array as arr[0]['list']
Once you have these values (10002,10003) then you can fetch the list values of remaining objects in the array whose id key matches one of the above values.
if(arr[i]['id'] == 10002 || arr[i]['id'] == 10003){
//fetch the list values
}
I have a data set that I'm pulling in from a database. It's one dimensional and I basically need to make it more structured. I refer to it as "flat".
I need to display a heading, and items under that heading that are related to the heading.
The data comes in as having and section_name (the heading) and item_name (items) and other data unique to each item like download URLs etc.
item_name(item)_______section_name(header)
first_________________Funds
second________________Funds
third_________________Funds
fourth________________Literature
fifth_________________Literature
sixth_________________Literature
seventh_______________Literature
eighth________________DueDilligence
I don't know what any of the names will be for the items or sections, or how many items, sections, or items per section. As I said, it's very flat. This needs to be fully dynamic which is why this is complicating things for me.
Here is what I've done.
API call to retrieve data. Store data in a state as an array (it comes in as an array of objects).
I create an empty array to store my newly structured data.
I loop through the data with a foreach.
I create a new object for my new data to add to the new array so I can loop over it later.
I first check to make sure the data exists.
To create the headers I check to see if my new empty array is actually empty OR my section_name is not the same as the last one.(in the original data array I got from the API call)
I store the section_names as an object in the new array (newArray.push(newObject)
I've gotten this far. Now I need to take the item_names that correlates to the section_names and store them in the object under each header name, or at least in the same index.
_generateInfo() {
let dataArray = this.state.stepTwoData
let newArray =[]
dataArray.forEach(function(item, index) {
let newObject = {}
if (index > 0) {
if (newArray.length === 0 || item.investor_portal_section_name !== dataArray[index -1].investor_portal_section_name) {
newObject["name"] = item.investor_portal_section_name
newObject["items"] = []
newArray.push(newObject)
}
})
console.log(newArray)
}
I tried pushing the items to the "number" array on my new object and that doesn't seem to work properly. Sometimes it will duplicate my newObject.name
Checking if the newObject.name === the section_names in the array and push it to the "number" array in my new object just creates new key-value pairs so it's still not correlating.
I tried looping through again in the if statement and if section_name === newObject.name then create a newObject and push it, but it would only push one of the items repeatedly instead of going through all of them.
I need to loop through and create a header (one header per different section_name). Then add each item that corresponds to the section_name to it. like this
[
{section_name(header): "Funds",
items: [
{
name: item_name,
sku: item_sku,
url: item_url
},
{
name: item_name,
sku: item_sku,
url: item_url
}]
},
{section_name(header):"Literature",
items: [
{name: item_name,
sku: item_sku,
url: item_url
},
{
name: item_name,
sku: item_sku,
url: item_url
}]}
]
Using associative array (dictionary) to segregate you data itmes by categories will do the job.
I've drafted some POC code that illustrates the idea. The key element there is buildAssociativeArray function
const raw_data = [
{item_name: "first", section_name: "Funds"},
{item_name: "second", section_name: "Funds"},
{item_name: "third", section_name: "Funds"},
{item_name: "fourth", section_name: "Literature"},
{item_name: "fifth", section_name: "Literature"},
{item_name: "sixth", section_name: "Literature"},
{item_name: "seventh", section_name: "Literature"},
{item_name: "eighth", section_name: "DueDilligence"},
]
function buildAssociativeArray(data) {
const dictionary = {};
for (var i = 0; i < data.length; i++) {
const item = data[i];
const section = item.section_name;
var dictEntry = dictionary[section];
if (!dictEntry) {
dictEntry = [];
dictionary[section] = dictEntry;
}
dictEntry.push({
name: item.item_name,
// other fields like sku: item_sku or url: item_url may follow here
});
}
return dictionary;
}
const dictionary = buildAssociativeArray(raw_data);
console.log(dictionary);
/*
At this point
dictionary == {
"Funds": [
{
"name": "first"
},
{
"name": "second"
},
{
"name": "third"
}
],
"Literature": [
{
"name": "fourth"
},
{
"name": "fifth"
},
{
"name": "sixth"
},
{
"name": "seventh"
}
],
"DueDilligence": [
{
"name": "eighth"
}
]
}
*/
// Associcative array dictionary itself allows to further solve you task using for (var key in dictionary) {...} operator
// If however you need to obtain the data structure looking exactly like the one in your question you may go further with following function
function transformAssociativeArray(dictionary) {
const array = [];
for (var key in dictionary) {
const items = dictionary[key];
const newEntry = {
section_name: key,
items: items,
}
array.push(newEntry);
}
return array;
}
const array = transformAssociativeArray(dictionary);
console.log(array);
/*
At this point
array == [
{
"section_name": "Funds",
"items": [
{
"name": "first"
},
{
"name": "second"
},
{
"name": "third"
}
]
},
{
"section_name": "Literature",
"items": [
{
"name": "fourth"
},
{
"name": "fifth"
},
{
"name": "sixth"
},
{
"name": "seventh"
}
]
},
{
"section_name": "DueDilligence",
"items": [
{
"name": "eighth"
}
]
}
]
*/
I'm trying to disable booked times from calendar, depending on the date. My goal is to create an array, which holds objects with single date and array of booked times.
I have created an api, which outputs something like this:
"bookings": [
{
"_id": "5ce1b8792598adasf452",
"workType": "Nail polishing",
"client": "Mary Johnson",
"date": "2019-05-31T00:00:00.000Z",
"bookingTime": "09:00"
},
{
"_id": "5ce1b8753hs53gasf452",
"workType": "Makeup",
"client": "Kate Bush",
"date": "2019-05-31T00:00:00.000Z",
"bookingTime": "10:00"
}
]
I've tried using Sets, filters, but I just can't seem to wrap my head around how to implement it to my own code.
Snippet of my code:
bookedTimes: []
fetchBookedTimes() {
axios.get("http://localhost:8080/api/bookings").then(res => {
for (var i = 0; i < res.data.bookings.length; i++) {
this.bookedTimes.push({
date: moment(res.data.bookings[i].date).format("YYYY-MM-DD"),
times: [res.data.bookings[i].bookingTime.substring(0,2)]
});
}
});
}
I expect the output to be
bookedTimes: [
{
date: "2019-05-31",
times: ["09", "10"]
},
{
date: "2019-06-01",
times: ["10", "11"]
}
]
But the actual output is
bookedTimes: [
{
date: "2019-05-31",
times: ["09"]
},
{
date: "2019-05-31",
times: ["10"]
},
{
date: "2019-06-01",
times: ["10"]
},
{
date: "2019-06-01",
times: ["11"]
}
]
As per the code, the actual output is correct. You are looping the response and pushing the data to an array. If you want to group them by date, then you have to create an object and then convert it to the expected output.
var result = res.data.bookings.reduce(function (defaultValue, booking) {
var date = moment(booking.date).format("YYYY-MM-DD");
defaultValue[date] = defaultValue[date] || {date: date, times: []};
defaultValue[date].times.push(booking.bookingTime.substring(0,2));
return defaultValue;
}, {});
console.log(Object.values(result));
You can simply use reduce()
const arr = [
{
"_id": "5ce1b8792598adasf452",
"workType": "Nail polishing",
"client": "Mary Johnson",
"date": "2019-05-31T00:00:00.000Z",
"bookingTime": "09:00"
},
{
"_id": "5ce1b8753hs53gasf452",
"workType": "Makeup",
"client": "Kate Bush",
"date": "2019-05-31T00:00:00.000Z",
"bookingTime": "10:00"
},
{
"_id": "5ce1b8753hs53gasf452",
"workType": "Makeup",
"client": "Kate Bush",
"date": "2019-06-31T00:00:00.000Z",
"bookingTime": "11:00"
},
{
"_id": "5ce1b8753hs53gasf452",
"workType": "Makeup",
"client": "Kate Bush",
"date": "2019-06-31T00:00:00.000Z",
"bookingTime": "12:00"
}
]
const res = arr.reduce((ac,{date,bookingTime}) => {
ac[date] = ac[date] || {date,bookingTime:[]}
ac[date].bookingTime.push(bookingTime.slice(0,2));
return ac;
},{})
console.log(Object.values(res))
You're pushing values directly into array but you need to group them by date so you can use an object and then push values to array in the end
Here temp is used to group values by date
We check for date it exists we push the time value to times array if not we create a new property on temp
In the end we push values to this.bookedTimes array
fetchBookedTimes() {
axios.get("http://localhost:8080/api/bookings").then(res => {
let temp = {}
for (var i = 0; i < res.data.bookings.length; i++) {
let date = moment(res.data.bookings[i].date).format("YYYY-MM-DD"),
let time = [res.data.bookings[i].bookingTime.substring(0,2)]
temp[date] = temp[date] || {date: date, times:[]}
temp[date].times.push(time)
});
}
this.bookedTimes.push(Object.values(temp))
});
}
First, check if the date of already in the array. Check if 'times' already exist in 'object.times', if not, push it to the 'object.times' array.
Please see the code below.
const date = moment(res.data.bookings[i].date).format("YYYY-MM-DD");
const times = res.data.bookings[i].bookingTime.substring(0, 2);
const arrayIndex = bookedTimes.findIndex(item => item.date === date);
//Check if date already exist in array
if (arrayIndex !== -1) {
//Check if 'times' already exist in 'object.times'
if (!bookedTimes[arrayIndex].times.includes(times)) {
//Push 'times' in 'object.times'
bookedTimes[arrayIndex].times.push(times);
}
} else {
//Push a new object into the array
bookedTimes.push({
date: date,
times: [times]
});
}
As stated above I am using NODE/Express backend and trying to parse out some data before I send it to the front-end.
I have an array of objects(items) and want to parse out a certain field in each item, particularly the description and the geolocation. It seems like it works just fine, but I have a couple of issues I am running into.
First I will show you one of the items to show you what it was before:
{
"_id": {
"$oid": "59925302e12872a81b28099e"
},
"offer": "19f5d9ef37b30311",
"txid": "389eb024f8869d787954c74d1653b8358e581cb4c81358361ffac662875bceec",
"expires_in": 13770133,
"expires_on": 1516531809,
"expired": false,
"height": "46411",
"category": "for sale",
"title": "Jack Garratt Signed Deluxe CD",
"quantity": "1",
"currency": "USD",
"sysprice": 415240000000,
"price": "35.00",
"ismine": false,
"commission": "0",
"offerlink": "false",
"private": "No",
"paymentoptions": 2,
"paymentoptions_display": "BTC",
"alias_peg": "sysrates.peg",
"description": "{\"description\":\"Signed, near mint double CD Only played a very few times\",\"media\":{\"defaultIdx\": 0,\"mediaVault\": [{\"mediaType\":\"img\",\"mediaURL\":\"http://i.imgur.com/bB7QjDR.jpg\"}]}}",
"alias": "Signed, near mint double CD Only played a very few times http://i.imgur.com/bB7QjDR.jpg",
"address": "1GR389Tki2LS3jScFUhrVxVnXdPdED5839",
"alias_rating_display": "0.0/5 (0 Votes)",
"offers_sold": 0,
"geolocation": "{\"coords\":{\"lat\":36.8518706,\"lng\":-123.5029326}}",
"alias_rating_count": 0,
"alias_rating": 0,
"safetylevel": 0,
"safesearch": "Yes",
"offerlink_seller": "",
"offerlink_guid": "",
"time": {
"$date": "1970-01-18T04:29:58.326Z"
},
"cert": "",
"__v": 0
}
Next I will show you how I parse the data I want. I particularly want a description geolocation and a new field media.
let newResults = [];
let updatedItem = {};
results.map((item, i) => {
const newDescription = JSON.parse(item.description);
const newGeolocation = JSON.parse(item.geolocation);
console.log(newGeolocation)
updatedItem = item;
updatedItem.geolocation = newGeolocation;
updatedItem.media = newDescription.media;
updatedItem.description = newDescription.description;
newResults.push(updatedItem);
return newResults;
});
console.log(newResults[24]);
Here is the result of console.log(newResults[24]):
{ _id: 59925302e12872a81b2809a3,
offer: '17fff08820c6da06',
txid: 'f27ec82c4cd694ecfdf061ebff7709a6154e39767595f7da08e4b2a40503c816',
expires_in: 26828208,
expires_on: 1529589884,
expired: false,
height: '276435',
category: 'for sale',
title: 'Marijuana Flavoured Vape E-Liquid 10ml 6mg',
quantity: '19',
currency: 'GBP',
sysprice: 1912000000,
price: '2.00',
ismine: false,
commission: '0',
offerlink: 'false',
private: 'No',
paymentoptions: 1,
paymentoptions_display: 'SYS',
alias_peg: 'sysrates.peg',
description: 'Marijuana Flavoured E-Liquid 10ml 6mg',
alias: 'Marijuana Flavoured E-Liquid 10ml 6mg',
address: '1DNeg3CrRFx6PuLcCry26p9y2XiTzTTFqw',
alias_rating_display: '0.0/5 (0 Votes)',
__v: 0,
offers_sold: 0,
geolocation: '[object Object]',
alias_rating_count: 0,
alias_rating: 0,
safetylevel: 0,
safesearch: 'Yes',
offerlink_seller: '',
offerlink_guid: '',
time: Sun Jan 18 1970 02:32:37 GMT-0600 (Central Standard Time),
cert: '' }
As you can see the data seems to have been parsed for the description, but the geolocation is giving me a weird [object Object] even though if I console log it inside the map it gives me each of the parsed data and they look fine.
Something else that I want to note here is that the media field is not even there. But if I were to console.log(newResults[24].media) it shows me the parsed data. But if I do try to access it on the front end like item.media I get undefined which is expected since it does not show up.
You are misusing map(). map() will return an object out of it. Try using something like this:
let newResults = results.map((item, i) => {
const {
media,
description
} = JSON.parse(item.description);
const geolocation = JSON.parse(item.geolocation);
return {
geolocation,
media,
description
};
});
console.log(newResults[24]);
If you want to tack these properties onto the item (without mutating the original item) you can use Object.assign() which will dump all the properties of the objects from the second argument onward into whatever the first argument is with priority given to later arguments.
In other words, we are going to return the value returned by the call to Object.assign({}, item, {...new props...}) and that call is going to create a new Object {} then dump all the properties from item into that new Object and then it is going to dump all the properties from {...new props...} on that first {} argument and will overwrite properties if they are already there.
let newResults = results.map((item, i) => {
const {
media,
description
} = JSON.parse(item.description);
const geolocation = JSON.parse(item.geolocation);
return Object.assign({}, item, {
geolocation,
media,
description
});
});
Additionally, when printing nested objects in node.js with console.log(), node will truncate the output rather than printing the whole arrary. Consider this code:
let tmp = [
{
foo: "Bar",
fizz: [
{
buzz: "hello"
}
]
}
];
console.log(tmp);
Will print:
[ { foo: 'Bar', fizz: [ [Object] ] } ]
The object is still fine, and if you try to dereference the nested object itself with console.log(tmp[0].fizz[0].buzz); You will get the output: hello.
Try
results.map((item, i) => {
const newDescription = JSON.parse(item.description);
const newGeolocation = JSON.parse(item.geolocation);
console.log(newDescription.media)
updatedItem = item;
updatedItem.geolocation = item.geolocation; //just assign geolocation
updatedItem.media = JSON.stringify(newDescription.media); //stringify the media object
updatedItem.description = newDescription.description;
newResults.push(updatedItem);
return newResults;
});