Here's what I'm using to get plain response object with non-stringified values and all nested associations from sequelize
v4 query.
With plain JavaScript (ES2015+):
const toPlain = response => {
const flattenDataValues = ({ dataValues }) => {
const flattenedObject = {};
Object.keys(dataValues).forEach(key => {
const dataValue = dataValues[key];
if (
Array.isArray(dataValue) &&
dataValue[0] &&
dataValue[0].dataValues &&
typeof dataValue[0].dataValues === 'object'
) {
flattenedObject[key] = dataValues[key].map(flattenDataValues);
} else if (dataValue && dataValue.dataValues && typeof dataValue.dataValues === 'object') {
flattenedObject[key] = flattenDataValues(dataValues[key]);
} else {
flattenedObject[key] = dataValues[key];
}
});
return flattenedObject;
};
return Array.isArray(response) ? response.map(flattenDataValues) : flattenDataValues(response);
};
With lodash (a bit more concise):
const toPlain = response => {
const flattenDataValues = ({ dataValues }) =>
_.mapValues(dataValues, value => (
_.isArray(value) && _.isObject(value[0]) && _.isObject(value[0].dataValues)
? _.map(value, flattenDataValues)
: _.isObject(value) && _.isObject(value.dataValues)
? flattenDataValues(value)
: value
));
return _.isArray(response) ? _.map(response, flattenDataValues) : flattenDataValues(response);
};
Usage:
const res = await User.findAll({
include: [{
model: Company,
as: 'companies',
include: [{
model: Member,
as: 'member',
}],
}],
});
const plain = toPlain(res);
// 'plain' now contains simple db object without any getters/setters with following structure:
// [{
// id: 123,
// name: 'John',
// companies: [{
// id: 234,
// name: 'Google',
// members: [{
// id: 345,
// name: 'Paul',
// }]
// }]
// }]