I'm newbie with nodejs. What I want to do is load users data, insert it to array and then assign it to variable.
If in PHP, I need to load data using my model.
I already have one method in nodejs to retrieve all users data (I already create the API).
This is my API routes :
router.get('/', ctl.getAllUser);
ctl.getAllUser refers to this method :
getAllUser(req, res, next) {
db.any('SELECT * FROM users')
.then((data) => {
if (data.length === 0) {
throw abort(404, 'No user data yet', 'Empty user table');
}
return res.status(200).json({
status: 'success',
data,
message: 'Retrieved all users data',
});
})
.catch(err => next(err));
},
usually I access it using :
http://localhost:5000/api/v1/users
But I don't know how to load it, and assign it to one variable.
This is the format that I want.
var users = [{
id: 1,
name: "indra.gunawan",
email: "indra.gunawan#gmail.com",
password: "123456"
}, {
id: 2,
name: "Jamie Christian",
email: "j.christianm#gmail.com",
password: "123456"
}];
module.exports = users;
Since your getAllUser() function returns a promise you need to subscribe it.
Something like this:
ctl.getAllUser().subscribe(data => console.log(data));
Related
How can i display newest user post in my app? i have a backend route which display user post but i want that route display latest post of user So how can i do that in my code?
My code:
router.get('/postdata', async (req, res) => {
try {
// Find all users in the database
const users = await User.find();
// Map over the users array and return an array of objects
// with the same username, profile_image, and postImage
const userData = users.flatMap(user => {
return user.posts.map(post => ({
username: user.username,
profile_image: user.profilepic,
postImage: post.post,
}));
});
return res.json(userData);
} catch (err) {
return res.status(500).json({ error: err.message });
}
});
If your posts model has created_at or updated_at properties that keep track of when an image was uploaded, you could use that to sort the array in your map.
Let's say your userData array has similar output to this.
[
{
username: 'user1',
profile_image: 'https://your_domain.com/user1-profile.jpg',
postImage: 'https://your_domain.com/user1-post1.jpg',
created_at: '2023-01-01T11:00:00.000
},
{
username: 'user2',
profile_image: 'https://your_domain.com/user2-profile.jpg',
postImage: 'https://your_domain.com/user2-post1.jpg',
created_at: '2023-01-01T12:00:00.000
}
]
Then you can sort the array before rendering it.
const sorteduserData = userData.sort((a, b) => {
return new Date(b.created_at) - new Date(a.created_at);
});
It's a good practice to have your backend do the sort to reduce overhead on the front-end and to have your application load faster.
Many of headless CMSs have these features built in.
I'm trying to response from my backend a piece of user id by using lodash, i tryed with id.slice(2, 9) but i get a response without _id. What i'm doing wrong? thanks in advance.
getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else
return res.status(200).json({ status: true, user: _.pick(user, ['_id'.slice(2, 9), 'domain', 'store', 'settings']) });
}
);
},
getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else {
let json = { status: true, user: _.pick(user, ['_id', 'domain', 'store', 'settings']) };
json.user._id = json.user._id.slice(2, 9);
return res.status(200).json(json);
}
}
);
},
Pick the parts you want
Slice the _id to replace it with just the part you want
return the object
Edit:
To cut the ObjectId is necessary first to parse to string, so you need something like this:
var newUserId = user._id.toString().substring(3,user._id.toString().length)
But there is a problem (I think, not tested). If you try to store the cut id into a model object, maybe mongoose don't allow you to add an string (and no valid ObjectId) value instead of ObjectId.
Maybe is neccesary create another object instead of the model with the schema.
Old answer (unrelated) but maybe usefull for somebody:
If you want to hide the result just use select() into your query.
You run a query and then select which fields do you want to get or not into the response.
The proper way to code it is as follows:
query.select({ field1: 1, field2: 1 });
//or
query.select('-field1');
//and many other ways
Docs here
I want to get updated table values after I add user to my "WOD" table. For instance, I have 2 users in my WOD table and after I add third user , I want to return a response to client with I have just inserted data (third guy). But now , I can only return first 2 users because I can not take updated values. Of course I can make another query to get updated table values after I insert, but is there any better solution ? Here is my codes;
const addUser = async (req, res) => {
try {
const { userId, wodId } = req.body;
if (!userId || !wodId) {
res.status(400).send({ status: false, message: 'need userId and wodId' });
}
const wod = await Wod.findByPk(wodId, {
include: [
{
model: User,
as: 'Participants',
through: { attributes: [] }
}
]
});
//check capacity if full.
if (wod.Participants.length >= wod.capacity) {
res
.status(403)
.send({ status: false, message: 'Capacity of this class is full!' });
}
const result = await wod.addParticipants(userId);
res.status(201).json({ status: !!result, wod });
} catch (error) {
res.status(500).send({ status: result, message: error.message });
console.log(error.message);
}
};
As a result of many-to-many association sequelize.sync will generate some functions for us. You are used addParticipants function and this returns an array that added to the assocation(userwod) table.
In this array you will find some id fields(join table fields) because you just run like this INSERT INTO 'user_wods' ('user_id''wod_id') VALUES (2,1). If you want to return the added user's information then you should run a SELECT * FROM 'user' WHERE 'id'=2.
You must call reload function for fetch the third guy.
await wod.reload()
server side
first here is how my Api works
searchPosts(params) {
return Api().get('search', params);
},
var postRouter = express.Router();
postRouter.get('/search', (req, res) => {
var db = req.db;
Post.find({ capacity: { $lte : req.body.capacity } }, function (error, q) {
if (error) { console.error(error); }
res.send({q})
})
})
with this, in my express route im able to do GET request on /search with the body
{
"capacity":60
}
for exemple, and have a working-as-intended response
{
"q": [
{
"obj":"obj"
},
]
}
Website side
in my .Vue file i call this function after a clic on a button
<v-btn
:disabled="!formIsValid"
flat
color="primary"
type="submit"
#click="searchPost">Search</v-btn>
methods: {
async searchPost() {
const response = await PostsService.searchPosts({
capacity: this.form.capacity,
equipments: this.createObjectFromArray(this.form.equipments),
date: this.form.date,
time: this.form.time,
});
console.log(response);
this.availableList = response.q;
},
in postman i'm correctly getting a q[] array with all my filtered object inside but on chrome request have no q inside
for my Api logs, i'm getting no error with Postman but
message:
'Cast to number failed for value "undefined" at path "capacity" for model "Post"',
name: 'CastError',
...
on the real test on the web
for information, this.availableList is defined inside Data()
data() {
const defaultForm = Object.freeze({
capacity: 0,
date: new Date().toISOString().substr(0, 10),
time: null,
equipments: [],
});
return {
form: Object.assign({}, defaultForm),
datePicker: false,
hourMenu: false,
availableList: [],
allList: [],
defaultForm,
};
},
Make sure your capacity field in your Post model includes type: number. It probably assumes by default that you're submitting a string value if you do not declare the type as number explicitly in the model.
Also, because you are awaiting the response, you also have to ensure your data assignment waits for the response to return. Try this:
methods: {
async searchPost() {
const response = await PostsService.searchPosts({
capacity: this.form.capacity,
equipments: this.createObjectFromArray(this.form.equipments),
date: this.form.date,
time: this.form.time,
})
.then( response => {
console.log(response);
this.availableList = response.data.q;
}
)}
Notice that instead of response.q I used response.data.q. I can't test this at the moment, so if it doesn't work try switching back to response.q.
i've edited my request like so in my vuejs file
async searchPost() {
const response = await PostsService.searchPosts({
capacity: this.form.capacity,
equipments: this.createObjectFromArray(this.form.equipments),
date: this.form.date,
time: this.form.time,
});
this.availableList = response.data;
},
in my Api ive changed it like so
searchPosts(params) {
return Api().get('search', { params });
},
what a fool was i to try to run a get command by passing parameters inside the body and not the query string
and so, i've updated my get function accordingly
postRouter.get('/search', (req, res) => {
var db = req.db;
Post.find({ capacity: { $lte : req.query.capacity } }, 'title description capacity equipments resa', function (error, q) {
if (error) { return res.status(500).send(error); }
res.send(q);
})
})
to find my find parameter inside req.query and no more the body
In my app I when I'm receiving posts from my NodeJS backend, in the Angular front end I'm trying to transform it using pipe() operator and using the map() function.
Here is my angular code that sends the http request to the backend,
getPosts(userId: string, currentPage: number) {
console.log(userId);
this.http.get<{message: string, posts: any, maxPosts: number }>
('http://localhost:3000/api/post/' + userId)
.pipe(map((postData) => {
console.log(postData);
return { posts: postData.posts.map((post) => {
return {
title: post.title,
content: post.content,
id: post._id,
imagePath: post.imagePath,
creator: post.creator
};
}),
maxPosts: postData.maxPosts};
}))
.subscribe(transformedPostsData => {
this.posts = transformedPostsData.posts;
this.postUpdate.next({
post: [...this.posts],
postCount: transformedPostsData.maxPosts
});
});
}
The backend function that receives this request is given below,
exports.getPosts = (req, res, next) => {
let fetchedPost;
let maxPosts = 10;
Post.find({ creator: req.params.userId }).then(post => {
if(post) {
res.status(200).json({
fetchedPost: post,
message: "Post successful",
max: maxPosts
});
} else {
res.status(500).json({
message: "Failed to get User Post"
});
}
});
}
My first assumption was the request was not carrying the userId against which it should retrieve the posts, then printed it with console.log(userId), it was fully fine.
Then I thought the backend was not returning any post or something null. Then I used console.log(postData), which printed the post data perfectly.
Here is what it looks like,
The other questions on SO regarding this error did not really match with my situation. I went through them carefully.
Even the minimum clue would mean great help. Thank you.