Why is array.push() not working correctly? - node.js

I have a function which returns an array of dishes from a firestore database.
With console.log I check that the dish I want to push is correctly formatted, then push it.
Finally I console.log the array to check if everything is alright.
Here is what I got:
https://image.noelshack.com/fichiers/2019/05/5/1549048418-arraypush.png
switch (type) {
case "Plats": {
this.nourritureCollection.ref.get().then(data => {
let platArray : Plat[] = [];
data.docs.forEach(doc => {
this.plat.name = doc.data().nourritureJson.name;
this.plat.price = doc.data().nourritureJson.price;
this.plat.ingredients = doc.data().nourritureJson.ingredients;
this.plat.type = doc.data().nourritureJson.type;
this.plat.availableQuantity = doc.data().nourritureJson.availableQuantity;
this.plat.isAvailableOffMenu = doc.data().nourritureJson.isAvailableOffMenu;
this.plat.imgUrl = doc.data().nourritureJson.imgUrl;
this.plat.temp = doc.data().nourritureJson.temp;
console.log(this.plat)
platArray.push(this.plat);
});
console.log(platArray)
return platArray;
});
break;
}...
plat is instantiated within my service component, I couldn't declare a new Plat() inside my function.
The expected result is that dishes should be different in my array of dishes.

You are updating this.plat in every iteration. So it will have n number of references in the array pointing to the same object, therefore, the values for all the array elements will be last updated value of this.plat
What you need is to create new Plat object for every iteration.
data.docs.forEach(doc => {
let plat: Plat = new Plat();
plat.name = doc.data().nourritureJson.name;
plat.price = doc.data().nourritureJson.price;
plat.ingredients = doc.data().nourritureJson.ingredients;
plat.type = doc.data().nourritureJson.type;
plat.availableQuantity = doc.data().nourritureJson.availableQuantity;
plat.isAvailableOffMenu = doc.data().nourritureJson.isAvailableOffMenu;
plat.imgUrl = doc.data().nourritureJson.imgUrl;
plat.temp = doc.data().nourritureJson.temp;
console.log(plat)
platArray.push(plat);
});
As pointed out in the comment, you can only use new Plat() if Plat is a class, if it is an interface, just let plat:Plat; would do.

Related

What is the best way in nodejs to compare two different array of objects based on one or more attributes/fields? The fields name can be different

let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.map(o1 => {
for (let i=0;i<obj2.length;i++) {
if (o1.field1 === obj2[i].attribute1) {
output.push(Object.assign(obj2[i], o1));
obj2.splice(i,1);
break;
}
}
});
console.log(output); //*[{attribute1:11,attribute2:12,field1:11,field2:12,field3:13},{attribute1:21,attribute2:22,field1:21,field2:22,field3:23},{attribute1:31,attribute2:32,field1:31,field2:32,field3:33}]*
The above code compares two different objects with its fields.
Here I am using 2 loops.
So my question is, do we have any better approach to achieve the same? Without two loops or using any package or the best way
You can use find to find the first element where the statement is true instead of looping and manually checking if the statement is true or false. Sadly find is also an iterative method but I don't see any other way to improve this. I am using filter to remove the elements that don't fulfil the condition o2.attribute1 === o1.field1.
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
const output = obj1.map(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
return obj2Value ? Object.assign(obj2Value, o1) : null;
}).filter(o => o !== null);
console.log(output);
Alternatively you can use forEach to do this:
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.forEach(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
obj2Value ? output.push(Object.assign(obj2Value, o1)) : '';
});
console.log(output);
There are several approaches to achieve this. Also remember map already returns a new array so no need to use push inside, just return. Check this for better understanding:
https://stackoverflow.com/questions/34426458/javascript-difference-between-foreach-and-map#:~:text=forEach%20%E2%80%9Cexecutes%20a%20provided%20function,every%20element%20in%20this%20array.%E2%80%9D .

Get Date from Nested Array of Objects and set that date as an Key in Node.js

I'm using Node.js I have data like this:
const data= [
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"},
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
I want data in this format:
expected Output:
"2022-09-06":[
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
"2022-09-08":[
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"}
]
"2022-09-07":[
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"}
]
Assuming the dates are always in the same format, I would do something like this:
function mapData(data){
// returns the given date as an string in the "%dd-%mm-%yyyy" format
const getDateWithoutTime = (dateString) => dateString.split("T")[0];
const mappedData = [];
for(const req of data){
const formattedDate = getDateWithoutTime(req.date);
// if the key already exists in the array, we add a new item
if(mappedData[formattedDate]) mappedData[formattedDate].push(req);
// if the key doesn't exist, we create an array with that single item for that key
else mappedData[formattedDate] = [req];
}
return mappedData;
}
Straightforward solution using regex:
let result = new Map();
for (const item of data) {
let date = item['date'].match(/\d{4}-\d{2}-\d{2}/)[0];
let items = result.get(date) || [];
items.push(item);
result.set(date, items)
}

Create a new key and or array to existing object in node.js

I have an existing object called unsettled:
var unsettled =
{
processor: 1,
dayFrom: 10,
dayTo: 12
}
Im trying to add an object called pName as I do with Angular, but it is not working.
unsettled.pname = "something"
It does work if unsettled.pname already exists on the object, but not if I want to create it.
Also, after a sql Query where I get several results, I need to create an array. Same thing, when I do
const pool = await utils.poolPromise
const recordset = await pool.request()
.query(sqlString)
if (recordset.rowsAffected[0] > 0) {
unsettled.processors = recordset.recordset;
}
Is not working either (the array processors is not being created).
Thanks.
For the array, try:
if (recordset.rowsAffected[0] > 0) {
unsettled["processors"] = recordset.recordset;
}
As for as pName, please try
unsettled["pname"] = "something"

Verify and select the right object in an array thanks to a find method which will match with a param json

I need some help,
I've got a json with some parameters inside of it, actually 2 but one day we may add some more in it.
I want to find between some object in an array the right one thanks to all parameters in the json
Am i using the right method ?
to be clearer, i want the param.t to match with the element.t, and the param.tid to match with the element.tid and if moving forward one more parameter cd1 is added to the JSON, this param.cd1 will match with element.cd1
thanks for the time !
const array1 = [{"t":"pageview","de":"UTF-8","tid":"UA-xxxxxxxxxx-17","cd1":"Without cookie"},{"t":"timing","de":"UTF-8","tid":"UA-xxxxxxxx-1","cd1":"France"}];
const param = { t: 'pageview', tid: 'UA-xxxxxxxxxx-17' }
for (let [key, value] of Object.entries(param)) {
console.log(`${key}: ${value}`);
}
const obj = array1.find(element => element.t == param.t);
If I am following correctly, you want to compare an array of objects to an object and based on some keys in 'param' object you want to filter out your array1.
const array2 = [{"t":"pageview","de":"UTF-8","tid":"UA-xxxxxxxxxx-17","cd1":"Without cookie"},{"t":"timing","de":"UTF-8","tid":"UA-xxxxxxxx-1","cd1":"France"}];
const param1 = { t: 'pageview', tid: 'UA-xxxxxxxxxx-17' }
const test = array2.find(checkExist);
const checkExist = el => {
return el.t == param1.t && el.tid == param1.tid; // here you can add your keys in future
}

Using GEE code editor to create unique values list from existing list pulled from feature

I'm working in the Google Earth Engine code editor. I have a feature collection containing fires in multiple states and need to generate a unique list of states that will be used in a selection widget. I'm trying to write a function that takes the list of state values for all fires, creates a new list, and then adds new state values to the new unique list. I have run the code below and am not getting any error messages, but the output is still statesUnique = []. Can anyone point me in the right direction to get the new list to populate with unique values for states?
My Code:
// List of state property value for each fire
var states = fire_perim.toList(fire_perim.size()).map(function(f) {
return ee.Feature(f).get('STATE');
}).sort();
print('States: ', states);
// Create unique list function
var uniqueList = function(list) {
var newList = []
var len = list.length;
for (var i = 0; i < len; i++) {
var j = newList.contains(list[i]);
if (j === false) {
newList.add(list[i])
}
}
return newList
};
// List of unique states
var statesUnique = uniqueList(states);
print('States short list: ', statesUnique)
Okay, I did not come up with this answer, some folks at work helped me, but I wanted to post the answer so here is one solution:
var state_field = 'STATE'
var all_text = 'All states'
// Function to build states list
var build_select = function(feature_collection, field_name, all_text) {
var field_list = ee.Dictionary(feature_collection.aggregate_histogram(field_name))
.keys().insert(0, all_text);
return field_list.map(function(name) {
return ee.Dictionary({'label': name, 'value': name})
}).getInfo();
};
var states_list = build_select(fire_perim, state_field, all_text)
print(states_list)

Resources