How to loop through JSON and add values to object - javascript

So I am having trouble figuring out how to create an array with two objects, looping through my object and adding some values to those objects in Javascript. Currently I have the following mock response:
const mockResponse =
{
"errors": [
{
"errorKey": "ERROR_NO_DELIVERY_OPTIONS",
"errorParameters": [
{
"errorMessage": "ERROR_DELIVERY_OPTIONS_YOU_SELECTED_NOT_AVAILABLE_NOW",
"partNumbers": [
19308033,
19114798
]
},
{
"errorMessage": "Ship to Home not available for these orderItemId",
"orderItemIds": [
10315031,
10315032
],
"availableShipModeId": 13203
},
{
"errorMessage": "Pickup At Seller not available for these orderItemIds",
"orderItemIds": [
10222222,
10333333
],
"availableShipModeId": 13203
}
],
"errorMessage": "ERROR_NO_DELIVERY_OPTIONS",
"errorCode": "ERROR_NO_DELIVERY_OPTIONS"
}
]
}
I would like to have an array with two objects. One for the first error message("Ship to home...") and another for the second error message("Pickup at Seller..."). I would like to then loop through the JSON and add each "orderItemIds" to there respective object. For example, 10315031,10315032 would go to the first object and 10222222, 10333333 to the second.

You can use reduce to loop through your errors and use the errorMessage property as a key
const result = mockResponse.errors[0].errorParameters.reduce((prev, item) => {
const { errorMessage, orderItemIds } = item;
if (prev[errorMessage]) {
prev[errorMessage] = [...prev[errorMessage], ...orderItemsIds];
} else {
prev[errorMessage] = orderItemIds
}
return prev
}, {})
Let me know if this does answer your question

Related

Loop to get value based on key name

Below is the JSON response I am getting. From this JSON response, I want to get the value of "fees" based on "detailComponent" with "FULL_FEE" only. But, somehow it gets the last value of "detailComponent" with "SUB_FEE" or others which is not correct.
I am sure not how to make this for loop condition to fix my issue. Can help to guide pls?
let data = {
"status": "SUCCESS",
"result": {
"originData": {
"detailType": "MSG",
"origin": [
{
"details": [
{
"detailComponent": "FULL_FEE",
"fees": 13564.00
},
{
"detailComponent": "SUB_FEE",
"fees": 8207.60
}
]
}
]
}
}
}
var getData = data.result.originData.origin[0].details[0].detailComponent;
console.log('getData: ', getData);
You can convert the array into a dictionary by the key (detailComponent) and the number (fees).
// Create Array
var items = [];
// Loop Through It
data.result.originData.origin[0].details.forEach((el, index) => items[el.detailComponent] = el.fees);
// Test
console.log(items["FULL_FEE"]);

Filter Array Using Partial String Match in Javascript

I have an array of objects where the value I need to filter on is buried in a long string. Array looks like:
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
},
So if I wanted to grab all the partnerId objects where value includes parent_sku how would I do that?
console.log(data.value.includes('parent_sku') returns cannot read property 'includes' of null.
EDIT:
Didn't think this mattered, but judging by responses, seems it does. Here's the full response object:
Response body: {
"data": {
"configurationByCode": [
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
}
I'm passing that into a re-usable function for filtering arrays:
const parentSkuPartners = filterArray(res.body.data.configurationByCode, 'parent_sku');
Function:
function filterArray(array, filterList) {
const newList = [];
for (let i = 0; i < array.length; i += 1) {
console.log('LOG', array[i].data.value.includes('parent_sku');
}
}
The problem is somewhere else. The code you've tried should work to find if a value contains a string – I've added it the snippet below and you'll see it works.
The issue is how you are accessing data and data.value. The error message clearly states that it believes that data.value is null. We would need to see the code around it to be able to figure out what the problem is. Try just logging to console the value of data before you run the includes function.
const data = {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}", "partnerId": 1
};
console.log('includes?', data.value.includes('parent_sku'));
You can use data.value.includes('parent_sku') as you have suggested. The issue here is that your object is nested inside an unnamed object.
try:
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
The problem was some of the values for value were null. Adding an extra conditional fixed it:
if (array[i].data.value !== null) {
Use lodash includes, and lodash filter like
let configurationByCode = [{
data: {
value: {
cols:["parent_sku"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 1
}
}, {
data: {
value: {
cols:["nothing"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 2
}
}];
let wantedData = _.filter(configurationByCode, (config) => {
return _.includes(config.data.value.cols, 'parent_sku');
});
console.log( wantedData );
https://jsfiddle.net/76cndsp2/

nodejs exported variable is not reusable on second hit

I am exporting a variable which is an array from file1.js:
// file1.js
const myArray = [
{
"name": "Judah Hendricks",
"email": "diam#lobortis.net",
"hobbies": [
{
"sports": "tennis",
"recent": true
},
{
"sports": "football",
"recent": false
},
{
"sports": "volleyball",
"recent": false
}
]
},
{
"name": "Jakeem Olsen",
"email": "at#tellus.org",
"hobbies": [
{
"sports": "swimming",
"recent": false
},
{
"sports": "running",
"recent": true
}
]
}
];
module.exports = { myArray };
and I am using it inside a route:
//main.js
const { myArray } = require('./file1.js');
router.get('/getData', (req, res) => {
dataBase.users.findOne({ email: req.user.email }, function(error, data){
if (data){
const myDataClone = [...myArray];
let newData = [];
newData = myDataClone.map( dt => {
dt.oldHobbies = []
for (let i = 0; i < dt.hobbies.length; i++) { // Cannot read property 'length' of undefined
if (dt.hobbies[i].recent) {
dt.recentHobby = dt.hobbies[i];
} else {
dt.oldHobbies.push(dt.hobbies[i]);
}
}
delete dt.hobbies;
return dt;
})
return res.status(200).json({userInfo: newData})
} else {
// do another
}
});
}
when I hit this route for the first time, it returns the expected data. my problem is when I revisit this route for the second time, I get Cannot read property 'length' of undefined for the dt.hobbies .
Could somebody help me understand what is wrong here and how to fix it?
The problem is here:
const myDataClone = [...myArray];
You're only shallow cloning the array, not deep cloning it; although the myDataClone array is different from myArray, the objects inside both arrays refer to the same objects in memory. So, when you
delete dt.hobbies;
the original object's hobbies property gets deleted as well, which means when you try to access the hobbies property of the object later, errors are thrown.
Fix it by making a deep clone at the beginning instead:
const myDataClone = JSON.parse(JSON.stringify(myArray));
As mentioned here, JSON.parse(JSON.stringify()) is probably the quickest way to deep clone objects. There are other methods like adding jQuery as a dependancy and using jQuery.extend, or writing your own custom cloning function, but serializing and deserializing works just fine.

Handling key value pair in response

I have the following response.
response: {
"json": {
"response":{
"servicetype":"",
"functiontype":"",
"statuscode":"0",
"statusmessage":"Success",
"data":
[
{
"graphtype":"headcountgraph",
"xlabel":"state",
"ylabel":"count",
"s1":"contact",
"s2":"User",
"data":
[
"Total Contacts: 1 Users: 36",
[
{
"x":"India",
"s1":"3",
"s2":"3",
"lat":"22",
"long":"77"
}
]
]
}
]
}
}
};
I need to Assign $scope.state = India,
How to fetch that ? I have tried giving $scope.state = json.response.data[0].data[1][0].x, which returns undefined data.
The thing is it has key and entry. I really lacking to fetch entry values from the code.
I gave code this way
$.each(data, function(key, entry) { x.push(parseInt(entry.x)});
but it gives me values [india] in my console.
Try giving $scope.state = response.json.response.data[0].data[1][0].x ;
Your statement doesn't start from the root response object.
You were very close.
json.response.data[0].data[1]
returns the following object:
{"x":"India","s1":"3","s2":"3","lat":"22","long":"77"}
You can filter by the x key with:
json.response.data[0].data.filter(o => o[0].x == "India")[0];

Creating a dynamic array

I need to create a dynamic array with a loop.. but I cant seem to get the desired results.
the array I want is:
{
"CategoryName": "somecategoryname",
"Date": "02-17-2012",
"Id": 24,
"ProductToHide": [
{
"IsHide": true,
"ProductId": "someid"
}
],
"ProductsToAdd": [
{
"MealSequence": "S1",
"ProductId": "Someid"
},
{
"MealSequence": "S2",
"ProductId": "Snack_11"
}
],
"UserId": "1"
}
and I am using the following function to add products:
addProduct: function(id){
var tempArr = [];
$.each(this.mCData.ChildCategories, function(i, item){
$.each(item.PList, function(j, jsonPr){
if (jsonPr.TID == id){
addProduct = new mealTypeProduct();
addProduct.data = jsonPr;
tempArr = addProduct.modifyProduct();
}
})
})
// queryStr = {"add" : tempArr};
// this.modificationArray.push(queryStr);
this.modificationArray['add'].push(tempArr);
console.log(this.modificationArray);
}
Its giving me the following error:
this.modificationArray.add.push is not a function
this.modificationArray['add'].push(tempArr);
the initializing is done in the following manner:
var mealType = {
chosenDate: new Date(), tabViewHtml: '',
modificationArray: [], saveArray: [],
}
What am I doing wrong?
This line:
tempArr = addProduct.modifyProduct();
replaces tempArr with a new value, so at the end of the $.each call it will have the value from the last matching product (which may not be an array) rather than being an array of all of them. If that is what you want then that's not a problem.
As to the actual error you quote: what type of thing is this.modificationArray? Does it have a member called add? Does that member have a push() function? Is it initialized properly, or is it left uninitialized? If the latter, then there's your problem: you need to initialize it before you can call push().
UPDATE: If this.modificationArray is initialized as [], as in the new sample code, then it is an array itself; it does not have an add member. The code should say this.modificationArray.push(tempArr).
Alternatively, if you really do want an add member, then this.modificationArray should be initialized as modificationArray : {add:[]}

Categories

Resources