Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize - How can I return JSON objects of the database results only?

So I'm wanting to have the database results returned and nothing else. At the moment I'm getting returned a large chunk of JSON data (Like below):

But I'm only needing the [dataValues] attribute. I don't want to have to use the this bit of JSON to retrieve it: tagData[0].dataValues.tagId.

I just noticed: When it finds and DOESN'T CREATE, it will return the JSON for the database results, but when it DOESN'T FIND and creates, it returns the un-needed JSON blob (Like below) Is there a way around this?

[ { dataValues:      { tagId: 1,        tagName: '#hash',        updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),        createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) },     _previousDataValues:      { tagId: 1,        tagName: '#hash',        createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),        updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) },     _changed:      { tagId: false,        tagName: false,        createdAt: false,        updatedAt: false },     '$modelOptions':      { timestamps: true,        instanceMethods: {},        classMethods: {},        validate: {},        freezeTableName: true,        underscored: false,        underscoredAll: false,        paranoid: false,        whereCollection: [Object],        schema: null,        schemaDelimiter: '',        defaultScope: null,        scopes: [],        hooks: {},        indexes: [],        name: [Object],        omitNull: false,        sequelize: [Object],        uniqueKeys: [Object],        hasPrimaryKeys: true },     '$options':      { isNewRecord: true,        '$schema': null,        '$schemaDelimiter': '',        attributes: undefined,        include: undefined,        raw: true,        silent: undefined },     hasPrimaryKeys: true,     __eagerlyLoadedAssociations: [],     isNewRecord: false },   true ] 

Instead of getting the big blob like the above I only need the RAW json results (Like below):

{ tagId: 1,        tagName: '#hash',        updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),        createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) }, 

I've used the following javascript. I did try add raw: true, but it didn't work?

    // Find or create new tag (hashtag), then insert it into DB with photoId relation module.exports = function(tag, photoId) {     tags.findOrCreate( {          where: { tagName: tag },         raw: true     })     .then(function(tagData){         // console.log("----------------> ", tagData[0].dataValues.tagId);         console.log(tagData);         tagsRelation.create({ tagId: tagData[0].dataValues.tagId, photoId: photoId })         .then(function(hashtag){             // console.log("\nHashtag has been inserted into DB: ", hashtag);         }).catch(function(err){             console.log("\nError inserting tags and relation: ", err);         });     }).catch(function(err){         if(err){             console.log(err);         }     });  } 

Edit:

So I've investigated a bit and it seems that the big JSON blob is only returned when Sequelize is creating and not finding.

Is there a way around this or not?

Edit 2:

Okay so I've found a workaround, which could be turned into a re-usable function. But if there's something built into Sequelize, I'd prefer to use that.

var tagId = "";  // Extract tagId from json blob if(tagData[0].hasOwnProperty('dataValues')){     console.log("1");     tagId = tagData[0].dataValues.tagId; } else {     console.log("2");     console.log(tagData);     tagId = tagData[0].tagId; }  console.log(tagId); tagsRelation.create({ tagId: tagId, photoId: photoId }) 

Edit 3:

So, I don't think there is an "Official" sequelize way of achieving this so I simply wrote a custom module which returns the JSON data that's needed. This module can be customised and extended to suit various situations! If anyone has any suggestions to how the module can be improved feel free to comment :)

In this module we're returning a Javascript Object. If you want to turn it into JSON just stringify it using JSON.stringify(data).

// Pass in your sequelize JSON object module.exports = function(json){      var returnedJson = []; // This will be the object we return     json = JSON.parse(json);       // Extract the JSON we need      if(json[0].hasOwnProperty('dataValues')){         console.log("HI: " + json[0].dataValues);         returnedJson = json[0].dataValues; // This must be an INSERT...so dig deeper into the JSON object     } else {         console.log(json[0]);         returnedJson = json[0]; // This is a find...so the JSON exists here     }      return returnedJson; // Finally return the json object so it can be used } 

Edit 4:

So there is an official sequelize method. Refer to the accepted answer below.

like image 219
James111 Avatar asked Dec 25 '15 06:12

James111


People also ask

How do I store JSON data in mysql using Sequelize?

Create a database and a Schema: var Sequelize = require('sequelize'), JsonField = require('sequelize-json'), db, User; db = new Sequelize('database', 'username', 'password', { dialect: 'sqlite', logging: false }); User = db. define('User', { username: Sequelize. STRING, jsonField: JsonField(db, 'User', 'jsonField') });

What is a sequelize model?

Models are the essence of Sequelize. A model is an abstraction that represents a table in your database. In Sequelize, it is a class that extends Model. The model tells Sequelize several things about the entity it represents, such as the name of the table in the database and which columns it has (and their data types).

Where is Sequelize?

Sequelize where option accepts an object describing the WHERE clause to add to your generated SQL query. For a WHERE clause with a simple condition, you can add a single property to the where object. The property name will be the column name and the property value will be the value you use to filter the query.


2 Answers

Though poorly documented, this does exist in Sequelize.

Couple Ways:

1. For any response object that resulted from a query, you can extract only the data you want by appending .get({plain:true}) the the response like so:

Item.findOrCreate({...})       .spread(function(item, created) {         console.log(item.get({           plain: true         })) // logs only the item data, if it was found or created 

Also make sure you are using the spread callback function for your type of dynamic query promise. And note that you have access to a boolean response, created, which signifies whether or not a create query was executed.

2. Sequelize provides the raw option. Simply add the option {raw:true} and you will receive only the raw results. This will work on an array of results, the first method should not, as get will not be a function of an array.

like image 171
rambossa Avatar answered Sep 22 '22 03:09

rambossa


If you want to work only with the values of an instance try to call get({plain: true}) or toJSON()

tags.findOrCreate( {      where: { tagName: tag } }) .then(function(tagData){      console.log(tagData.toJSON()); }) 
like image 26
Rudolf Manusachi Avatar answered Sep 21 '22 03:09

Rudolf Manusachi