Adding property to array of object with map and promises - javascript

The assignement of a new property to each object in array, obtained with an async function in map is not working.
Here is my code:
asyncFunction.then(array => {
var promises = array.map(obj => {
return otherAsyncFunction(obj._id).then(prop => {
obj.url = prop;
return obj
})
})
Promise.all(promises).then(function (results) {
console.log(results)
})
res.send(user.friends)
})
The console.log(results) displays the same array.
I've tried to log the new obj juste before the return obj and it displays also the old obj

I've finally found the answer: the array was somehow not mutable, I just copied the initial array with the following:
let b = JSON.parse(JSON.stringify(array));

Related

Simplifying a nested loop in a javascript function

I have this function in JS
function getMap(objectList) {
const objectMap = new Map();
IDS.foreach(id => {
const attribute = objectList.find(object => object.getId() === id);
if (attribute) {
objectMap.set(id, attribute);
} else {
objectMap.set(id, null);
}
}
This is a nested loop because of the find inside the for loop. How could this be simplified? If the nested loop cannot be simplified, can other parts be simplified?
Assuming object IDs are unique, it looks like all you really have to do is call getId on each object beforehand. The conditional operator may be used instead of if/else if you wish.
function getMap(objectList) {
const objectsById = new Map(
objectList.map(object => [object.getId(), object])
);
const objectMap = new Map();
for (const id of IDS) {
objectMap.set(id, objectsById.get(id) || null);
}
}
You could create an array with null entries for each ID, followed by entries for which you actually have values in objectList, and pass that array to the Map constructor:
function getMap(objectList) {
return new Map([
...IDs.map(id => [id, null]),
...objectList.map(object => [object.getId(), object])
]);
}
Using native code with a simple callback
const result = (IDS || []).map(function(id, idx, arr) {
const pos = (objectList || []).findIndex(object => object.getId() === id);
const output = [];
output[id] = (pos >= 0 ? objectList[pos] : null);
return output;
});
Hope this helps... ;D

nested functions returning undefined

hi I want to get the result of this function at once inside the items variable, but when I try to return items I get undefined value , can someone explain why and fix it please?
let arr= [[1,2,3,4],[5,6,7,8],['a','b','c','d']];
let colp = [0,1,3];
function selCol(arr,colp) {
let items = [];
return colp.forEach((element) => {
return arr.map((row) => {
items.push(row[element]);
return items;
});
});
}
Maybe you can return items, and in that case map is not necessary
function selCol(arr, colp) {
let items = [];
colp.forEach((element) => {
arr.forEach((row) => {
items.push(row[element]);
return items;
});
});
return items;
}
It is about the 'forEach'. forEach method returns undefined, if you want to return a value either map it or if you want to items in its mutated version, return it directly as such;
function selCol(arr, colp) {
let items = [];
colp.forEach((element) => {
return arr.map((row) => {
items.push(row[element]);
return items;
});
});
return items;
}

how to get rid of an array inside an array in javascript

const addressZip = person.get('addresses').filter((address) => address.get('legacy_id')).filter((newAddress) => (
getZIPErrors(newAddress.get('zip'))
))
when this function is executed it returns me as an
[array(0)] if it has no error
when it has an error it returns me as an [array(1)].
Instead of returning an array inside an array I just want to return a single array in this way if it has no error [] and if it has an error it should be like ['invalid']
You can implement a concatAll method within Array constructor, then use it to flatten your result:
Array.prototype.concatAll = function() {
return this.reduce((acc, curr) => acc = acc.concat(curr))
}
const addressZip = person
.get('addresses')
.filter(address => address.get('legacy_id'))
.filter(newAddress => getZIPErrors(newAddress.get('zip')))
.concatAll()

jQuery ui catcomplete get data object in loop object

Referring from the below code. i use catcomplete from jQuery ui and i want to get the country list from each catagory to show up when seaching but i get undefined what i do wrong ?
This my object array:
24:category:"Afrika"
country:1:{label: "Namibia"}
2:{label: "Sydafrika"}
3:{label: "Tanzania"}
4:{label: "Madagaskar"}
25:category:"Asien"
country:1:{label: "Private: Södra Indien"}
2:{label: "Indonesien"}
3:{label: "Filippinerna"}
4:{label: "Indien"}
5:{label: "Thailand"}
This my function:
$('#autocomplete').catcomplete({
source: function (request, response) {
//data :: JSON list defined
response($.map(TourArea, function (value, key) {
return {
category: value.category,
label: value.country.label,
}
}));
},
});
Result is: country array get undefined
Result
Now i find out and it work. all i need is just merge all object to be in one.
How to make multi id array object to all in one
let newData = Object.values(data).map(v => {
let x = [];
for (let k in v) x.push(v[k]);
return x;
}).reduce((c, v) => {
c = c.concat(v);
return c;
}, []);
And autocomplete function:
$('#autocomplete').catcomplete({
source: newData,
});
Done all working fine.

Create multidimensional javascript object from values in array using jquery .each loop

I need to create a javascript object using values stored in an array. Every value should be a new key inside the previous one. What would be the best approach to achieve this?
var option = ['level_1','level_2','level_3','level_4'];
$.each( option, function( key, value ) {
// ....
});
// I'm trying to get this result
var result = {
'level_1': {
'level_2': {
'level_3': {
'level_4':{}
}
}
}
}
You can use reduceRight for this, with the ES6 computed property name syntax.
const option = ['level_1','level_2','level_3','level_4'];
const obj = option.reduceRight( (acc, lvl) => ({ [lvl]: acc }), {});
console.log(obj);
In traditional function syntax it would be:
const obj = option.reduceRight(function (acc, lvl) {
return { [lvl]: acc };
}, {});
You have to keep track of where to put the next key. So, create a variable and initially set it to result, then on each pass through the array, move where that variable points to.
var option = ['level_1','level_2','level_3','level_4'];
var result = {};
var nextKeyGoesHere = result;
option.forEach( function( value ) {
nextKeyGoesHere[value] = {};
nextKeyGoesHere = nextKeyGoesHere[value];
});
console.log(result);
Can use Array#reduce()
var option = ['level_1','level_2','level_3','level_4'];
var res = {};
option.reduce((o, key) => (o[key] = {} , o[key]), res)
console.log(res)
you can use any of the other answers that use Array#reduce, however, if you'd like a recursive version here it is:
function _makeTree(arr, index, subtree){
if(index < arr.length){
subtree[arr[index]] = {};
return _makeTree(arr, index+1, subtree[arr[index]])
}
else return;
}
function makeTree(arr){
var tree = {};
_makeTree(arr, 0, tree)
return tree;
}
var arr = ['level_1','level_2','level_3','level_4'];
console.log(makeTree(arr));

Categories