Creating a dynamic array - javascript

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:[]}

Related

Access and extract values from doubly nested array of objects in JavaScript

I have an array of objects and within those objects is another object which contains a particular property which I want to get the value from and store in a separate array.
How do I access and store the value from the name property from the data structure below:
pokemon:Object
abilities:Array[2]
0:Object
ability:Object
name:"blaze"
1:Object
ability:Object
name:"solar-power"
How would I return and display the values in the name property as a nice string like
blaze, solar-power ?
I tried doing something like this but I still get an array and I don't want to do a 3rd loop since that is not performant.
let pokemonAbilities = [];
let test = pokemon.abilities.map((poke) =>
Object.fromEntries(
Object.entries(poke).map(([a, b]) => [a, Object.values(b)[0]])
)
);
test.map((t) => pokemonAbilities.push(t.ability));
Sample Data:
"pokemon": {
"abilities": [
{
"ability": {
"name": "friend-guard",
"url": "https://pokeapi.co/api/v2/ability/132/"
},
"ability": {
"name": "Solar-flare",
"url": "https://pokeapi.co/api/v2/ability/132/"
}
}
]
}
Then I am doing a join on the returned array from above to get a formatted string.
It just seems like the multiple map() loops can be optimized but I am unsure how to make it more efficient.
Thank you.
There is no need for a loop within loop. Try this:
const pokemon = {
abilities: [{
ability: {
name: 'friend-guard',
url: 'https://pokeapi.co/api/v2/ability/132/'
},
}, {
ability: {
name: 'Solar-flare',
url: 'https://pokeapi.co/api/v2/ability/132/'
}
}]
};
const pokemonAbilities = pokemon.abilities.map(item => item.ability.name).join(', ');
console.log(pokemonAbilities);

How to loop through JSON and add values to object

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

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"]);

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.

Manipulating objects in an array

I am new to JavaScript and been struggling to combine objects in the same array.
Here is what I have:
var testList = [{
'taskList1': 'task1 for taskList1',
},
{
'taskList1': 'task2 for taskList1',
},
{
'taskList2': 'task1 for taskList2'
},
{
'taskList2': 'task2 for taskList2'
}]
The array below is what I really want to get from above:
var testList = [{
'taskList1': 'task1 for taskList1',
'taskList2': 'task1 for taskList2'
},
{
'taskList1': 'task2 for taskList1',
'taskList2': 'task2 for taskList2'
}]
Could anyone please help me to transform my current array into the one above?
Thank you in advance.
Your data structure is quite inefficient in this case. I'd suggest to make it better by having the same array of objects, but each object should contain itemName and belongsTo as a reference to any collection (in your case - a taskList) you may pass there.
Here's a solution to your problem with a more flexible data structure on Codepen - https://codepen.io/Inlesco/pen/dReYgd
I've also added the restructured array of tasks below as an example that's used in the Codepen above.
var testList = [{
item: 'task1',
belongsTo: 'taskList1'
},
{
item: 'task2',
belongsTo: 'taskList1'
},
{
item: 'task1',
belongsTo: 'taskList2'
},
{
item: 'task2',
belongsTo: 'taskList2'
}]
There are many ways to approach this problem. I've just added probably the simplest one.
You can use a for statement to regroup objects with the same taskList ID in one object.
And of course your need to use the right conditions for that.
But the best way is as #Denialos said, to modify your data structure.
Per my comments above to the question, your desired data structure appears to be inverted, or "inside out". Given a list of items, and a set of tasks for each item, I would expect the outer element to be the list, and the inner element to be the set of tasks.
Given that, given your (current) input data I would use:
function restructure(taskList) {
var result = {};
for (var i = 0, n = taskList.length; i < n; ++i) {
// read current item
var item = taskList[i];
var key = Object.keys(item)[0];
var value = item[key];
// update the output
result[key] = result[key] || [];
result[key].push(value);
}
return result;
}
with resulting output:
{
taskList1: [ 'task1 for taskList1', 'task2 for taskList1' ],
taskList2: [ 'task1 for taskList2', 'task2 for taskList2' ]
}
That said, your input data model is also somewhat malformed, with each array element having an unknown key. You should look at what's actually producing that data and fix that if possible.

Categories

Resources