Node.js / Sequelize.js / Express.js - How to insert many-to-many association? (Synchronous / asynchronous?)

I have two models (Individual, Email) and I'm trying to insert Individual_Email into the created table using Sequelize commands. Although Sequelize creates the desired table, it returns the following error when trying to add / receive / install to / from this table: "Object [object Promise] does not have an" addEmail "method." What am I missing?

The Sequelize documentation says the models are User and Project, "This will add the getUsers, setUsers, addUsers methods to Project and getProjects, setProjects and addProject for the user."

It makes me believe (looking at promises) that I probably don't understand how to use Node's asynchronous functions. I tried both synchronous and asynchronous version of the insert, returning the same message above.

Pin documentation: http://docs.sequelizejs.com/en/latest/docs/associations/

the code:

routes /index.js

var express = require('express'); var router = express.Router(); var models = require('../models'); /* GET home page. */ router.get('/', function(req, res, next) { 'use strict'; var tIndividual, tEmail; tIndividual = models.Individual.create({ name: "Test" }); tEmail = models.Email.create({ address: " test@gmail.com " }); console.log(tEmail); res.render('index', { title: 'Express' }); }); module.exports = router; 

OR

 /* GET home page. */ router.get('/', function(req, res, next) { 'use strict'; var tIndividual, tEmail; tIndividual = models.Individual.create({ name: "Test" }).then(function(){ tEmail = models.Email.create({ address: " test@gmail.com " }).then(function(){ tIndividual.addEmail(tEmail).then(function(){ console.log("Success"); }); }) }); res.render('index', { title: 'Express' }); }); module.exports = router; 

models /index.js

 db.Individual.hasMany(db.Email, { as: 'Email', through: 'Individual_Email' }); db.Email.hasMany(db.Individual, { as: 'Individual', through: 'Individual_Email' }); 

How can I add the "Individual_Email" table in the best way? I assume that I need to do this synchronously in order to wait for the update, but I am open to any suggestions. Thanks!

+7
javascript promise
source share
3 answers

When you call .save() or .create() or other methods that return Promise, you should call .then() this promise. When it is solved, that is, when the object is saved / created / something-elsed, the then function will be called and will receive the saved / created object as a parameter.

So, your first attempt can be rewritten as:

 models.Individual.create({ name: "Test" }).then(function(createdIndividual) { // note the argument models.Email.create({ address: " test@gmail.com " }).then(function(createdEmail) { // note the argument createdIndividual.addEmail(createdEmail) .then(function(addedEmail) { // note th-- well you get the idea :) console.log("Success"); }); }) }); 

The above code lacks a few important things, such as return for promises for better chaining and error handling, but this is the beginning. I would recommend Bluebird documentation on this subject (that uses the Promise library that Sequelize uses, but there are others)

+8
source share

You can reduce Pyramid of Doom using promises:

 var createdIndividual; models.Individual.create({ name: "Test" }).then(function(createdIn) { // note the argument createdIndividual = createdIn; return models.Email.create({ address: " test@gmail.com " }); }).then(function(createdEmail) { // note the argument return createdIndividual.addEmail(createdEmail); }).then(function(addedEmail) { // note th-- well you get the idea :) console.log("Success"); }); 
+2
source share

I figured out how to solve it in one way, but let me know if there is a better way.

My solution: Since .create () returned the promise, instead I used .build (), which returned an instance and only added to "Individual_Email" after both were saved synchronously. Then I called the add method on the instance returned from .build () and inserted into the table.

My code is:

 var tIndividual, tEmail; tIndividual = models.Individual.build({ name: "Test" }); tEmail = models.Email.build({ address: ' test@gmail.com ' }); tIndividual.save() .success(function(){ tEmail.save() .success(function(){ tIndividual.addEmail(tEmail); }); }); 
0
source share

All Articles