AlexZeDim
AlexZeDim

Reputation: 4352

Add/Merge element from from one Object to another Object inside array

I have the following code in my async function

async function test () {
    try {
        const aucs = await auctions.find({owner: 'owner', place: 'place'}).limit(15);
        const item = await Promise.all(aucs.map(async aucs => {
            const map = await items.find({id: aucs.item});
            return map[0]
        }));
        --->we are here [1]
    } catch (err) {
        console.log(err);
    }
}

test();

and the point [1] I have two arrays avaliable which contain another objects (both are responces from Mongo) here they are:

aucs = [ { _id: 5c00faa4936359120ceb3632,
    auc: 177215422,
    item: 130251,
    price: 26000000,
    lastModified: 1543567955000,
    date: 2018-11-30T08:53:56.290Z,
    __v: 0 },
    { _id: 5c00faa4936359120ceb363f,
    auc: 177215440,
    item: 130251,
    price: 26000000,
    lastModified: 1543567955000,
    date: 2018-11-30T08:53:56.290Z,
    __v: 0 },... ]

and

item = [ { _id: 5bcd8a6134cdd1223cd3239b,
    id: 130251,
    name: 'TEST_NAME_1',
    __v: 0 },
    { _id: 5bcd8a6134cdd1223cd3239b,
    id: 130252,
    name: 'TEST_NAME_2',
    __v: 0 },...]

And I'd like to add to aucs[i]every element in aucs, item[i].name (name: 'TEST_NAME_1') Like:

combined = [ { _id: 5c00faa4936359120ceb3632,
        auc: 177215422,
        item: 130251,
        name: 'TEST_NAME_1',
        price: 26000000,
        lastModified: 1543567955000,
        date: 2018-11-30T08:53:56.290Z,
        __v: 0 },...]

I'm trying to use for loop with auc[i].name = item[i].name or using aucs.push() but for some unknown reason it wasn't worked for me. I receive error for .push is not a function and for loop didn't add anything. So maybe someone have any idea?

Note: 1

actually solve one problem with item, mongo returns me array inside array like [ [ { ...} ] ] so I should using return map[0] to fix it.

Note: 2

both of aucs and item are object according to typeof and have .length option (they are both the same length and should be all the time. So they are not promises

Note: 3

let merged = {...aucs, ...item}; returns me

{ '0': { _id: 5bcd8a6134cdd1223cd3239b,
     id: 130251,
     name: 'JewelCraft',
     icon: 'inv_jewelcrafting_70_jeweltoy',
     stackable: 1,
     isAuctionable: true,
     __v: 0 }...

but not what I need to

Upvotes: 2

Views: 72

Answers (2)

Ashh
Ashh

Reputation: 46491

Would be more superior and faster if you use some aggregation trick here

auctions.aggregate([
  { "$match": { "owner": "owner", "place": "place" }},
  { "$lookup": {
    "from": "items",
    "let": { "item": "$item" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$id", "$$item"] }}}
    ],
   "as": "item"
  }},
  { "$limit": 15 }
])

Upvotes: 1

danh
danh

Reputation: 62686

If I understand correctly, the aim is to create a new collection of aucs like the ones found, each updated to include an item name from the item collection where the item has a matching id.

let aucs = [ { _id: "5c00faa4936359120ceb3632",
    auc: 177215422,
    item: 130251,
    price: 26000000,
    lastModified: 1543567955000,
    date: "2018-11-30T08:53:56.290Z",
    __v: 0 },
    { _id: "5c00faa4936359120ceb363f",
    auc: 177215440,
    item: 130251,
    price: 26000000,
    lastModified: 1543567955000,
    date: "2018-11-30T08:53:56.290Z",
    __v: 0 } ];
 
item = [ { _id: "5bcd8a6134cdd1223cd3239b",
    id: 130251,
    name: 'TEST_NAME_1',
    __v: 0 },
    { _id: "5bcd8a6134cdd1223cd3239b",
    id: 130252,
    name: 'TEST_NAME_2',
    __v: 0 }];
    
// create a new collection of aucs modified to include the names of matching items
let combined = [];
aucs.forEach(auc => {
    let combinedAuc = Object.assign({}, auc);
    combined.push(combinedAuc);
    let matchingItem = item.find(i => auc.item === i.id);
    if (matchingItem) combinedAuc.name = matchingItem.name
});

console.log(combined)

Upvotes: 1

Related Questions