简体   繁体   中英

Trouble to destroy a model with Sequelize

What is happening?

I am trying to destroy one model via params . But when I try to destroy, it appears this error at the console.

(node:13350) UnhandledPromiseRejectionWarning: TypeError: results.map is not a function
    at Query.handleSelectQuery (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/abstract/query.js:261:24)
    at Query.formatResults (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/mysql/query.js:118:19)
    at /home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/sequelize/lib/dialects/mysql/query.js:71:29
    at tryCatcher (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/promise.js:729:18)
    at _drainQueueStep (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:93:12)
    at _drainQueue (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:86:9)
    at Async._drainQueues (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:102:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/home/vagnerwentz/Documents/freelance/autoparanaiba-api/node_modules/bluebird/js/release/async.js:15:14)
    at processImmediate (internal/timers.js:439:21)
    at process.topLevelDomainCallback (domain.js:130:23)
(node:13350) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13350) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

The route that call the function

router.delete('/agricultural/announce/:id', passport.authenticate(), (req, res) => {
    AnnouncementAgricultural.destroy(req, res);
})

The function

exports.destroy = async (req, res) => {
    if (!await authorize(req, res, true)) {
        return res.status(400).json({ success: false, errors: "unauthorized" })
    }

    await sequelize.query('SET FOREIGN_KEY_CHECKS=0;', { type: sequelize.QueryTypes.SELECT });

    await Annoucement.destroy({
        where: { id: req.params.id }
    }
    ).then((result) => {
        console.log(result);
        res.status(200).json({ success: true })
    }).catch((err) => {
        console.log(err)
        res.status(400).json({ success: false, errors: err.errors })
    });
}

The QueryType you send tells Sequelize how to format the results. If you are performing SET and send QueryType.SELECT you will get an error because it tries to use .map() on an object:

const results = await sequelize.query("SET NAMES utf8mb4;", {
    type: sequelize.QueryTypes.SELECT }
);
// -> TypeError: results.map is not a function

Sadly, in many places the docs confuse Raw Query (sending SQL in plain text) and using QueryTypes.RAW (which only should be used to format the results of queries that are not SELECT, UPDATE, etc.). Thus, one could assume that if you are making a Raw Query you should use the same QueryType to make the query "raw". At the very least, we should be able to assume it only affects how data is returned. The Sequelize documentation :

If you are running a type of query where you don't need the metadata, for example a SELECT query, you can pass in a query type to make sequelize format the results

Confusingly, if you are using a SELECT then none of these examples cause issues:

sequelize.query("SELECT * FROM table");
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.SELECT });
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.UPDATE });
sequelize.query("SELECT * FROM table", { type: sequelize.QueryTypes.RAW });

But if you use RAW on an UPDATE Sequelize tries to map an object

sequelize.query("UPDATE table SET createdAt = NOW();", {
    type: sequelize.QueryTypes.RAW }
);
There was an uncaught error TypeError: results.map is not a function
    at Query.handleSelectQuery ([...]/node_modules/sequelize/lib/dialects/abstract/query.js:261:24)
    at Query.formatResults ([...]/node_modules/sequelize/lib/dialects/mysql/query.js:123:19)
    at Query.run ([...]/node_modules/sequelize/lib/dialects/mysql/query.js:76:17)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async [...]/node_modules/sequelize/lib/sequelize.js:619:16

So, because you are using SET you could, as @Anatoly says, change from QueryTypes.SELECT to QueryTypes.RAW to avoid the error. But if you don't need the results then don't pass a QueryType at all.

await sequelize.query('SET FOREIGN_KEY_CHECKS=0;');
// -> keep on keepin' on

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM