2017-10-03 2 views
1

J'ai créé une boucle pour ajouter des produits (avec des données) à différentes régions. Pour commencer, je veux ajouter tous les produits à toutes les régions. Je vais ensuite (dans une opération différente) retirer des produits de ces régions.Dupliquer des objets après avoir créé un objet dans l'objet dans Mongoose (MongoDB, Node.JS, express)

La prémisse du site est que les objets pourront être réservés par un utilisateur dans une région, ce qui rendra cet objet indisponible dans cette région mais toujours disponible dans d'autres régions. Je sauvegarde la région des utilisateurs lors de mon inscription et je leur permets seulement de voir les objets disponibles dans leur région.

J'ai créé des objets appelés Régions et j'ajoute chaque produit à un tableau dans les régions. La raison pour laquelle je les stocke dans les régions est que dans l'avenir je m'attends à des centaines de produits différents et je crois que le simple retour de tous les éléments dans un tableau régional sera beaucoup plus facile sur le serveur que la vérification individuelle de chaque produit.

Mon problème est que

lors de l'exécution de mon code, je reçois des copies de chaque objet dans ma page.

Le code J'utilise est:

dummyregions.forEach(function(seed){ 
    Region.create(seed, function(err, region){ 
     if(err){ 
      console.log(err); 
     } else { 
      dummyproducts.forEach(function(seedprod){ 
       Product.create(seedprod, function(err, product){ 
        if(err){ 
         console.log(err); 
        } else { 
         region.products.push(product); 
         region.save(); 
        } 
       }); 
      }); 
     } 
    }) 
}); 

dummyRegions est un objet, contenant un nom "string" et un tableau = []

dummyproducts contient un nom "string", catégorie « string "et une URL de l'image miniature « string »

J'ai seulement 4 articles de test dans les produits factices et 3 régions, mais cela est le résultat que je reçois: Duplicate Items on each Region

Toute aide serait grandement appréciée!

+0

Êtes-vous sûr que ce ne sont pas dans la base de données déjà ? – Paul

+0

J'efface les deux collections (région et produits) de la base de données avant d'exécuter le script ci-dessus. J'ai vérifié deux fois pour m'assurer qu'ils ne sont pas présents avant le script. Les doublons sont créés avec le code ci-dessus. – Corey01

Répondre

0

Parce que Array.forEach bloque pour les méthodes asynchrones, vous obtenez des doublons. Pour une version asynchrone de Array.forEach, vous pouvez utiliser le module async ou Promises.

Ces derniers peuvent suivre cet exemple (non testé):

let regionsPromise = Region.insertMany(dummyregions); 
let productsPromise = Product.insertMany(dummyproducts); 

Promise.all([regionsPromise, productsPromise]) 
    .then(([regions, products]) => { 

     console.log(regions); // check regions array 
     console.log(products); // check products array 

     let ids = regions.map(r => r._id); 
     console.log(ids); // check ids 

     Region.update(
      { '_id': { '$in': ids } }, 
      { '$push': { 'products': { '$each': products } } }, 
      { 'multi': true } 
     ); 
    }) 
    .catch((err) => { 
     /* Error handling */ 
     console.error(`Error ${err.message}`); 
    }); 

et pour une version qui utilise de ES7 async/await:

(async() => { 

    try { 

     const regions = await Promise.all(dummyregions.map(async (reg) => { 
      await Region.create(reg); 
     })); 

     const products = await Promise.all(dummyproducts.map(async (prod) => { 
      await Product.create(prod); 
     })); 

     for (let region of regions) { 
      await region.findByIdAndUpdate(region._id, { 
       '$push': { 
        'products': { '$each': products } 
       } 
      }); 
     } 

     /* 

     if (regions && regions.length) { 
      await Promise.all(
       regions.map(async (r) => { 
        await r.findByIdAndUpdate(r._id, { 
         '$push': { 
          'products': { '$each': products } 
         } 
        }); 
       }) 
      ); 
     } 

     */ 

    } catch (err) { 
     console.error(`Error ${err.message}`); 
    } 
})(); 
+0

Merci beaucoup pour votre réponse. Je ne suis pas vraiment familier avec ES16 et ES17, donc j'ai vraiment besoin de lire à ce sujet> J'ai essayé d'implémenter la première solution que vous avez suggérée, en utilisant des promesses, et je ne rencontre aucune erreur, mais le les régions n'ont aucun objet à l'intérieur d'elles. De toute évidence, je ne vous demande pas d'écrire mon code pour moi (bien que j'apprécie vraiment votre aide), mais avez-vous des indications sur les endroits où je peux rechercher pourquoi il n'y a pas de produits dans mes régions? Merci encore! – Corey01

+0

Vous pouvez vous connecter pour consoler les résultats des promesses remplies, c'est la première étape que je pourrais prendre, comme dans la modification ci-dessus. Vérifiez également si votre modèle 'Regions' a le champ de tableau' products' explicitement déclaré dans la définition de schéma. – chridam

+0

Les régions et les produits sont créés correctement, les identifiants se connectent correctement et chaque région contient un tableau vide de produits [] lors de la connexion. Il semble que la fonction de mise à jour sur le modèle de région ne fonctionne pas correctement, j'ai essayé de le changer à ce qui suit: Region.findByIdAndUpdate ( {'_id': {'$ in': ids}}, {'$ push ': {' products ': {' $ each ': produits}}} ) }) Cependant, toujours pas de chance – Corey01