how to display all records using bookshelfjs - javascript

Why this is not displaying all channels. How can I display all channels.
new channelModel()
.fetch()
.then(function (channel) {
console.log(channel.attributes.name);
if (channel) {
res.json({error: false, status: 200, data: channel.attributes.name});
} else {
res.json({error: true, status: 404, data: 'channel does not exist'});
}
})
.otherwise(function (err) {
res.status(500).json({error: true, data: {message: err.message}});
});
Any idea?

Use fetchAll:
new channelModel()
.fetchAll()
.then(function (channels) {
channels.forEach(function(channel) {
// do something with each channel
});
// or just respond with JSON array assuming this is an Express app:
res.send(channels.toJSON());
})
I haven't actually tried the forEach function, but according to bookshelf.js documentation it should work. If you're doing a REST service, you probably want to just serialize the collection (array) as JSON.

Related

How to post data as an array object using axios

I have a function that I am using axios to post data to nodeJS rest api. The problem that I am having is that axios added post a list with the object instead of just the array object. Please help me fix this.
The function receives the follow from "documents"
{
_id: '6149290b197615d32c515dab',
instantMessage: false,
isComplete: true,
},
{
_id: '614a249636503d7aa9fb138d',
instantMessage: false,
isComplete: true,
},
{
_id: '614a2bf5560184026def253a',
date: '2021-09-21',
title: 'Not getting erro',
},
{
_id: '614a2c6a560184026def253d',
date: '2021-09-21',
title: 'Every thing working',
}
my function is as follow:
async function SaveAsTemplate(documents) {
const result = await axios
.post('http:localhost/templates', {
documents,
})
.catch(function (error) {
// handle error
console.warn(error.message);
});
return result;
}
in my nodeJS project where the query is received I am console.log the data and I am getting the follow results:
documents: [
{
_id: '6149290b197615d32c515dab',
instantMessage: false,
isComplete: true,
},
{
_id: '614a249636503d7aa9fb138d',
instantMessage: false,
isComplete: true,
},
{
_id: '614a2bf5560184026def253a',
date: '2021-09-21',
title: 'Not getting erro',
},
{
_id: '614a2c6a560184026def253d',
date: '2021-09-21',
title: 'Every thing working',
}
]
How can I use axios where it only give me the object without documents in front.
When I use Postman and other tools to send query to post I do not have this problem everything come out correct. Only have issues when using axios
You're doing
const result = await axios
.post('http:localhost/templates', {
documents,
})
which is the same as:
const result = await axios
.post('http:localhost/templates', {
documents: documents,
})
try:
const result = await axios
.post('http:localhost/templates', documents)
async function SaveAsTemplate(documents) {
const result = await axios
.post('http:localhost/templates', {
headers: {
'Content-Type': 'application/json',
},
body: documents,
})
.catch(function (error) {
// handle error
console.warn(error.message);
});
return result;
}
or you can try to change array to object first and then you assign on body post

How to make mongoose.find not return all data if passed with empty string

I have Videos data with title name on each and writing an search api which will get videos data matching title name
exports.findbytitle = (req, res) => {
let userPattern = new RegExp(req.body.title, "i");
Videos.find({ title: userPattern })
.then((video) => {
res.send({ success: true, video });
})
.catch((err) => {
res.send({ success: false, err });
});
};
Problem here is if userPattern matches I get proper videos, but if userPattern is empty string example: ("title": "") I get all videos instead of error.
What changes should I make to get error if userPattern is passed as empty string?
As you know only if the title is empty then why aren't you adding a condition before query?
if(!req.body.title) {
return res.send({ success: false, err: new Error("Not found")})
}
Just throw custom error if req.body.title is not sent or is empty string:
exports.findbytitle = (req, res, next) => {
if(!req.body.title) return res.status(400).json({success:false, message: 'Title is missing.'})
let userPattern = new RegExp(req.body.title, "i");
Videos.find({ title: userPattern })
.then((video) => {
res.send({ success: true, video });
})
.catch((err) => {
res.send({ success: false, err });
});
};

How can I reorganize my return in an async function?

let's say I've got a function where I'm fetching for some data from a DB.
findById(id) {
return Model.findById(id)
}
I need to reorganize the return from the user data like this:
{
name: "Tom",
age: 57
}
into something like this:
{
message: "User is found successfully",
success: true,
user: user
}
So far I can manage with that with a Promise "then" section, like this:
return Model.findById(id)
.then(user => {
if (!user) {
logger.warn(`Coundn't find user with id: ${id}`);
return { message: `Coundn't find user with id: ${id}`, success: false, user: null };
}
return { message: `User with id: ${id}`, success: true, user: user };
})
.catch(err => {
if (err) {
logger.error(err.message);
return { message: err.message, success: false, user: null };
}
})
Can I do the same with a async/await and return my reorninazed return?
Because so far it returns the user object from the DB:
async findById(id) {
return await this.model.findById(id, function (user, err) {
if (err) {
console.log('test');
logger.error(err);
return { message: err.message, success: false, user: null };
}
if (!user) {
logger.warn(`Coundn't find user with id: ${id}`);
return { message: `Coundn't find user with id: ${id}`, success: false, user: null };
}
return { message: `User with id: ${id}`, success: true, user: user };
});
}
Thanks in advance!
Most database APIs do NOT support both a callback and a promise at the same time. If you pass a callback, they do not return a promise. Pick one style or the other. Your first approach using .then() works just fine as that is all promise-based.
Your second approach does not work because you're passing a regular callback. That tells the database to NOT return a promise because you're using the older callback style, but you're trying to use that promise.
If you want to use async/await, you could do so like this:
async findById(id) {
try {
let user = await this.model.findById(id);
if (user) {
return { message: `User with id: ${id}`, success: true, user: user };
} else {
logger.warn(`Coundn't find user with id: ${id}`);
return { message: `Coundn't find user with id: ${id}`, success: false, user: null };
}
} catch(e) {
logger.error(err);
return { message: err.message, success: false, user: null };
}
}
FYI, you can remove the if (err) test in the .catch() handler from your first code block. If .catch() is triggered, there is an error - you don't need to test if one is there.

Express not saving after req.user.save()

In the following code, the user isn't getting saved.
router.patch('/onboard', auth.requireLoggedIn, function (req, res) {
if (req.user.settings.onboarding[req.body.page]) {
res.status(409).json({
status: 'Error: Trying to onboard for a page that has already been onboarded.',
});
}
console.log(req.body.page);
req.user.settings.onboarding[req.body.page] = true;
console.log(req.user.settings.onboarding);
req.user
.save()
.then(function (res) {
console.log(res);
res.status(200).json({
status: 'Successful',
});
})
.catch(function () {
res.status(500).json({
status: 'Internal server error.',
});
})
;
});
req.user.settings.onboarding.equityCalculator starts off as false and I want to set it as true. All of the console logs indicate that this is happening. However, when I check my database, it isn't updated.
By "check my database" I mean "look in Robo 3T". But I also mean querying the database and looking at the user I get back.
Furthermore, the following code works perfectly. I don't see how this code works but the code above does not work.
router.patch('/subscribe-to-email', auth.requireLoggedIn, function (req, res) {
if (req.user.emailOptIn) {
res.status(409).json({
status: 'You can\'t subscribe if you are already currently subscribed.',
});
}
req.user.emailOptIn = true;
req.user
.save()
.then(function () {
res.status(200).json({
status: 'Successful',
});
})
.catch(function () {
res.status(500).json({
status: 'Internal server error.',
});
})
;
});
Here is the relevant part of my User schema:
UserSchema = new mongoose.Schema({
emailOptIn: {
type: Boolean,
default: false,
required: true,
},
settings: {
type: mongoose.Schema.Types.Mixed,
required: true,
default: defaultSettings,
},
...
});
Try the following, it worked for me in a similar situation:
req.user.settings.onboarding[req.body.page] = true;
req.user.markModified('settings.onboarding');
req.user.save()
The lack of saving seems to occur when setting array indices, like in your example. Marking the modified array allows the saving to occur properly.

Mongoose inside a promise change happens late

I am writing an API in NodeJS in which I use Mongoose and BlueBird. Regarding promise chain, my data was supposed to go through waterfall functions but it didn't. Let my example start with getTagNames to get some JSON , feeding data to retrieveTag to query and end up with res.json().
exports.getTagValues = function (req, res) {
var userId = req.params.uid;
getTagNames(req, res)
.then(retrieveTag)
.then(function (data) {
console.log('tags', data);
res.json(200, data);
})
.catch(function(err){
console.log('err', err);
//handle Error
})
}
Here is my toy data,
function getTagNames(req, res) {
var userId = req.params.uid;
return new Promise.resolve({
'userId': userId,
'variables': [
{ id: 1, name: 'hotel', type: 'String' },
{ id: 2, name: 'location', type: 'String' }
],
})
}
The way I query data. After querying inside mongo, I check whether or not have a document with userID. In case not, insert and return document. Note Tag is my mongo model
function retrieveTag(data){
Tag.findOne({'userId': data.userId})
.exec()
.then( function(tag){
if (tag) {
console.log('result', tag);
// do something ...
return tag;
}
else {
var newTag = new Tag({
advertiserId: advertiserId,
variables: variables
});
newTag.save()
.then(function () {
console.log('newTag', newTag);
return newTag;
});
}
})
}
Here is my result (userId is 1), my expectation is console.log('tags', data); occurs after all then data should not be undefined
tags undefined
GET /api/tag/values/1 200 3ms
newTag { __v: 0,
userId: '1',
_id: 581b96090e5916cf3f5112fe,
variables:
[ { type: 'String', name: 'hotel', id: 1 },
{ type: 'String', name: 'location', id: 2 } ] }
My question is how can I fix it. If there's some unclear, please help me correct.
The explanation is a bit unclear, but if I follow you right you loose data in the promise resolvement chain.
When reading your code, I notice that retrieveTag does not return the Mongoose promise. To let .then in getTagValues use the data found in retrieveTag.
So change to this:
function retrieveTag(data){
return Tag.findOne({'userId': data.userId})
.exec()
.then( function(tag){
...
})
}

Categories

Resources