Sequelize fails to provide a model instance as a return value

In the official documentation of Sequelize (http://docs.sequelizejs.com/en/v3/docs/raw-queries/), it mentions:

If you pass a model, the returned data will be instances of that model.

// The caller is the model definition. This allows easy mapping of a query to a predefined model
sequelize.query('SELECT * FROM projects', { model: Projects }).then(function(projects){
  // Each record will now be an instance of Project
})

A model has been defined for a resource named agent.

module.exports = function(sequelize, DataTypes) {
   let Agent = sequelize.define('Agent', {
      responseStatus: DataTypes.STRING,
      agentnum: {
        type: DataTypes.STRING,
        primaryKey: true,
        allowNull: false,
        field : 'agentno'
      },
      fname :  {
        type: DataTypes.STRING,
        allowNull : false,
        field: 'fname'
      },
      lname : {
        type: DataTypes.STRING,
        allowNull: false,
        field : 'lname'
      }, 
      fullname : {
        type: DataTypes.STRING,
        allowNull : false,
        field: 'full_name'
      }, 
      status : {
        type: DataTypes.STRING,
        allowNull: false,
        field: 'business_status'
      }, 
      loginDate: DataTypes.DATE
  }, {
      freezeTableName: false,
      timestamps: false
  });

  return Agent;
};

However, when using sequelize.query with my query and specifying the model as Agent, I encounter an error thrown from sequelize:

TypeError: this.model.bulkBuild is not a function

The stack trace points to

sequelize\lib\dialects\abstract\query.js:675
.

This issue persists until I apply a QueryType of sequelize.QueryTypes.RAW. At this point, the query executes but returns a JSON response that is not an instance of my Agent model. The JSON response contains field names that should have been mapped to.

I have imported my model according to the instructions in their express sample (https://github.com/sequelize/express-example/blob/master/models/index.js). The models collection confirms that my Agent model is included.

import Sequelize from 'sequelize';
import config from './config';

export default callback => {
  const sequelize = new Sequelize(config.database, config.username, config.password, config.params);

  sequelize.sync().then(function() {
    let db = { }

    let agentModel = sequelize.import('model/agent.js');
    db[agentModel.name] = agentModel;

    db.sequelize = sequelize;
    db.Sequelize = Sequelize;

    db.sequelize.authenticate().then(function() {
      console.log('CONNECTION OK');
    });


    callback(db);

  }).catch(function(err) {
    console.log('FAILED TO CONNECT: ', err.message);
  });
}

I expect the query to return an instance of Agent when invoked (e.g., through a POST request to my API). I am utilizing MS SQL Server 2008 R2.

Any suggestions are welcomed. Thank you.

EDIT 1/30 Here is the code generating the sequelize object and passing in the model. Although the model collection shows that my item is added, it does not have any properties.

connectDb: (function () {
        var sequelize;
        function createInstance() {
            var sequelizeInstance, connectedAndAuthenticated;
            sequelizeInstance = new Sequelize(config.database, config.username, config.password, config.params);
            connectedAndAuthenticated = sequelizeInstance.authenticate();
            connectedAndAuthenticated.sequelize = sequelizeInstance;
            connectedAndAuthenticated.Sequelize = Sequelize;

            var model = sequelizeInstance.import('../src/model/agent.js');


            return connectedAndAuthenticated;
        }
        return {
            getInstance : function () {
                if (!sequelize) {
                    sequelize = createInstance();
                }
                return sequelize;
            }
        };
    }())

EDIT 1/26 After modifying the QueryTypes, I realized two things - inadvertently creating a table in the database with the name of the model (Agent) and having the object returned with an empty value for tablename property. Even though the schema and tablename are specified by me, since the query is a stored procedure involving multiple queries and tables, it doesn't directly map to an object named Agent in my database. However, based on the documentation, it seems that this shouldn't matter, as I am creating my own model tied to the query result.

Answer №1

Understanding the sequelize documentation can be challenging. Allow me to clarify how to use sequelize in a simple and clean way.

var models = require('../models');

Ensure that your code file includes the above line, with a directory named models containing index.js as well as the Project model. Be cautious - only correctly configured models should be present in this directory. Next, add the following code snippet:

 models.sequelize.query("select 1 as val").then(function(result){
console.log(result)
})

This will allow you to test the connection. Additionally, utilize the find query like so:

 models.Projects.findAll().then(function(result){
    console.log(result)
    })

Answer №2

Seems like a minor typo to me. It appears that Agent is not defined within your scope. Instead of using Agent, you should be passing agentModel or whatever name you assigned to the import.

let agentModel = sequelize.import('model/agent.js');    
db.sequelize.query("DECLARE @response VARCHAR(256); EXEC API_Login @agenum = N'" + agentNum + "', @hashedPassword = '" + password + "', @response = @response OUTPUT; SELECT @response AS N'response'",{ model: agentModel, type: sequelize.QueryTypes.RAW}) .spread(function(Agent) { res.status(200).json(Agent); }) .catch(function(err) { handleError(err, res); });

Please take note that I'm using {model: agentModel, ...} and not {model: Agent, ...} because Agent is not defined outside of the callback function.

The error message

TypeError: this.model.bulkBuild is not a function
logically points towards Agent not being an actual model but something different (or undefined).

UPDATE

You mentioned in the comments on the post below that: "I have synchronized the model - the query tries to create a table instead of binding to the provided agent model" and "It shouldn't be creating a table".

Why do you believe this to be the case? Creating the table during sync() is standard behavior for Sequelize.

I think there might be a misunderstanding regarding how Sequelize operates. It generates a table for each registered model during synchronization. If it cannot create that table, it may result in returning an invalid model, leading to errors.

Models are directly associated with specific database tables; this is the core functionality of Sequelize. Each model instance represents a row in that table. If you're working with stored procedures, you may prefer utilizing the native database library and defining your own abstraction layer.

You can potentially disable or override all default data synchronization between the model and the underlying DB table, but at a certain level of complexity, you'd essentially be designing your own abstraction library from scratch.

Perhaps you can utilize Sequelize according to your requirements, but at the very least, refrain from calling sync(). Without defining your own beforeSync hook, sync() will always create a table in your schema:

Model.prototype.sync = function(options) {
  options = options || {};
  options.hooks = options.hooks === undefined ? true : !!options.hooks;
  options = Utils._.extend({}, this.options, options);

  var self = this
    , attributes = this.tableAttributes;

  return Promise.try(function () {
    if (options.hooks) {
      return self.runHooks('beforeSync', options);
    }
  }).then(function () {
    if (options.force) {
      return self.drop(options);
    }
  }).then(function () {
    return self.QueryInterface.createTable(self.getTableName(options), attributes, options, self);
  })
  ...
  }).return(this);
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

validation for grouped radio inputs

I'm having a small issue with appending error states. I have 7 radio inputs and after submitting, I see 7 error states under the group. Can someone assist me in modifying the code? <form class="register-form"> <div class="co ...

Launch a YouTube video within a sleek and stylish Bootstrap modal popup

I am currently extracting video data from my SQL table. The fields in the table are as follows: - sidebar_video_id (auto increment) - sidebar_video_nev - sidebar_video_link (full URL) - sidebar_video_v_id (video ID at the end of the URL) What I'm tr ...

Only the initial setInterval function is currently active, despite multiple being set simultaneously

I am currently working on developing a webpage with a dynamic background featuring moving clouds. The code I have written for this project utilizes jQuery as shown below. browserWidth = 0; browserHeight = 0; clouds = 4; cloudSpeed = 50; $(function() { ...

Issue with mouseover functionality not functioning properly while hovering over a dropdown menu

My friend and I are relatively new to the world of coding with HTML, CSS, and a bit of JavaScript. We're currently facing an issue with our dropdown menu implementation. We have created buttons and added a dropdown menu using li and ul elements. Initi ...

Unable to set values to an array of objects in JavaScript

Currently, I am facing an issue in my node.js project where I am unable to assign values to an array of objects. This problem has occurred before, but I just can't seem to figure out the root cause. My suspicion is that it might be related to variable ...

Conceal a row in a table after successfully executing a delete query using Ajax

Currently, I am facing an issue with hiding rows within a while loop. My goal is to hide an entire row once the delete query has been successful. The deletion query itself is functioning correctly, but I require assistance in properly hiding the row. Any h ...

What is the type of the props function in a Typescript/React functional component?

As a newcomer to React, I am exploring ways to modify this code without utilizing any form of the add function that is Dependency Injected into the component. Most resources suggest using the React mouse click event type, which only accepts one parameter ...

Output a variable that is generated from invoking an asynchronous function

I'm currently in the process of developing an application that is going to leverage the capabilities of a SOAP server through the use of the https://github.com/vpulim/node-soap module. One of the main challenges I am facing is how to efficiently crea ...

The field value exceeds the limit of characters allowed (3184658) and should be submitted using form

This field in DTO is dedicated to storing content. @IsNotEmpty({ message: 'Nội dung này không được để trống!' }) @IsString() @MinLength(0, { message: 'Độ dài bài viết không hợp lệ!' }) content: string; While th ...

Encountering a problem when utilizing window.ethereum in Next Js paired with ether JS

Experiencing some difficulties while utilizing the window.ethereum in the latest version of NextJs. Everything was functioning smoothly with NextJs 12, but after upgrading to NextJs 13, this error started popping up. Are there any alternative solutions ava ...

Unexpected "<" and dual output in jade include seem to defy explanation

i am currently redesigning my website to incorporate dynamic includes. These includes are pre-rendered on the server and then passed to res.render() however, I am encountering unexpected occurrences of < and > on the page, along with the issue of th ...

Connect an EventListener in JavaScript to update the currentTime of an HTML5 media element

*update I have made some changes to my code and it is now working. Here's the link: I am trying to pass a JavaScript variable to an HTML link... You can find my original question here: HTML5 video get currentTime not working with media events javscr ...

Invoke the Java function via AJAX upon button press

In the file blank.jsp, there is a button as follows: <input class="submit_button" type="submit" id="btnPay" name="btnPay" value="Payment" style="position: absolute; left: 350px; top: 130px;" onclick="javascript:payment();"> After clicking this but ...

Obtaining the node-webkit GUI object from an HTML file that has been generated by Express

I have developed a node web application using Express and other Node modules. I am interested in turning this web app into a desktop application, and a friend recommended using Node Webkit. Node Webkit allows me to customize the appearance of the app to m ...

The fadeIn callback doesn't seem to function properly when triggered within the success function of jquery.ajax

Using AJAX, I fetch some data and prepend it to the body. Once displayed, I need to execute some client-side operations on this new element, such as rendering Latex using codecogs' script. Below is a snippet of my code: $.ajax({ /* ... */ success: fu ...

Switch out the text surrounded by two specific characters

Looking to remove a specific part of a string enclosed between two characters? For example, replacing all characters between "value=" and " " with "" so that the value is always an empty string. For instance: "<input value=98 name=anything>" Would ...

Updating a JSON property in JavaScript on the fly

I am looking to dynamically replace the content of "placeholder" with {"John": "Dough"} using a function call. This initial method seems to work fine: a = {foo:{bar:{baz:"placeholder"}}}; a.foo.bar.baz = {"John" : "Dough"}; console.log(JSON.stringify(a)) ...

Utilizing Jquery in the Customer Portal feature within the Salesforce platform

Struggling to incorporate a Visualforce page with Jquery UI and Salesforce Customer Portal. Unfortunately, Jquery UI seems to be taking precedence over the Standard Salesforce stylesheet. Is there a way to prevent this from happening? Any assistance on t ...

Rapidly refreshing user interface in real-time based on current status

I'm struggling to create a button that will smoothly open a menu. Initially, I thought setting the state on button click would work fine but now I realize that the first click does not have any effect on the state or class. It's only the second a ...

AngularJS does not "initiate" new DOM elements

I have been working on an AngularJS application recently, and here is a simplified version of the relevant parts: <div ng-app="myModule"> <div id='container'> <div say-hello-to name="Frank">f</div> < ...