My question is similar to this How to post query parameters with Axios?
Instead of posting, I want a get data request and I wanna pass the query param name to the request. It works in postman but not working in react.
const handleSubmit = async () => {
try {
const res = await axios.get(
"http://localhost:5000/api/products",
{},
{
params: {
name,
},
}
);
console.log(res.data);
} catch (err) {}
};
exports.retrieveProducts = (req, res) => {
Product.find(
{ name: { $regex: req.query.name, $options: "i" } },
(err, products) => {
if (err) res.status(500).json(err);
res.json(products);
}
);
};
You are using an empty object as config.
It should be
const handleSubmit = async () => {
try {
const res = await axios.get(
"http://localhost:5000/api/products",
{
params: {
name: 'whatever',
},
}
);
console.log(res.data);
} catch (err) {}
};
Related
I am using socket.io with express and typescript, when want to emit to particular logged in user it is not working, the rest is working fine, when new user join and other things, in App.ts in backend it looks like:
httpServer.listen(8000, () => {
console.log(`app is running on: http://localhost:8000`);
});
//SocketIO
const io = new Server(httpServer, {
cors: {
credentials: true,
},
});
app.set("socketio", io);
io.use((socket: SocketWithUser, next: any) => {
const token: any = socket.handshake.query.token;
if (token) {
try {
const payload = jwt.verify(
token,
<string>process.env.JWT_TOKEN
) as DataStoredInToken;
socket.userId = payload._id;
return next();
} catch (err) {
next(err);
}
} else {
return next(new Error("Access Denied"));
}
});
io.on("connection", (socket: SocketWithUser) => {
if (socket.userId) {
socket.join(socket.userId);
socket.emit("joined", `user ${socket.userId} joined`);
}
socket.on("disconnect", () => {
console.log("disconnect");
});
});
and in another route sockethandler
import { Request } from "express";
import { NotificationProps } from "types/notification";
export const sendNotification = (
req: Request,
notification: NotificationProps
) => {
const io = req.app.get("socketio");
io.sockets
.in(String(`${notification.receiver}`))
.emit("newNotification", notification);
};
the like post route looks like
export const likePost = async (req: RequestWithUser, res: Response) => {
const { postId } = req.body;
const post = await PostModel.findById(postId);
if (!post) return res.status(400).send({ msg: `post does not exist` });
const checkIfLiked = post.likes.find(
(item: any) => String(item.user._id) === String(req.user_id)
);
if (!checkIfLiked) {
await post.updateOne(
{
$push: { likes: { user: req.user_id } },
},
{ new: true }
);
const notification = new Notification({
sender: req.user_id,
receiver: post.user,
notificaitonType: "like",
});
await notification.save();
sendNotification(req, notification);
return res.status(200).send({ success: true });
}
const postWithOutLike = await post.updateOne(
{
$pull: { likes: { user: req.user_id } },
},
{ new: true }
);
return res.status(200).send({ postWithOutLike });
};
in the frontend react app just calling it like:
socketIo().on("newNotification", (data) => {
console.log({ data });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
any help please?
I believe you need want io.in
// to all clients in room
io.in(notification.receiver).emit('newNotification', notification);
Ref
this is the frontend where i call the api:
componentDidMount() {
try {
this.setState({ id: this.props.Id })
await api.get('/match/query/' + this.props.Id).then(res => {
console.log(res.data)
this.setState({ users: res.data })
})
} catch (Error) {
console.log("ERROR " + Error);
};
}
backend for the api call:
router.get('/query/:id', async (req, res) => {
try {
const user = await match.findById(req.params.id);
// console.log("this is user from query-------------------", user);
let m = moment(user.date)
m1 = m.subtract(4, 'h');
m = moment(user.date)
m2 = m.add(2, 'hours');
let query = await match.find({ $and: [{ date: { $lte: m2 } }, { date: { $gte: m1 } }, { _id: { $ne: req.params.id } }] });
// console.log("query from query----------------------------", query)
res.json(query)
}
catch (err) {
Console.log(err)
}
})
the dev options in chrome has nothing returned:
the same page after about 5 mins:
I'm a bit stumped and was wondering if anyone could help. Whenever I call an axios post, the network tab shows that the request is pending and ultimately fails. When I try the same call through Robo 3T, it updates succesfully.
Can anyone give me some insight? Thank you!
Here's the route I'm using:
router.post('/upvote/reply/id/:id',
// passport.authenticate('jwt', { session: false }),
async (req, res) => {
await Posts.findOneAndUpdate(
{ "comments._id": mongoose.Types.ObjectId(req.params.id) },
{
$inc: { "comments.$.points": 1 },
$push: { "comments.$.upvotedBy": req.user._id },
$pull: { "comments.$.downvotedBy": req.user._id },
},
(err, result) => {
if (err) {
return res.status(404).json({
success: false,
error: err,
message: 'Post not upvoted!',
})
}
else {
return res.status(200).json({
success: true,
data: result
})
}
})
.catch(err => console.log(err))
})
Here's how I'm calling my API route:
handleReplyUpvote = (id) => {
this.setState(prevState => {
const updatedReplies = prevState.replies.map(item => {
if (item._id === id) {
try {
axios
.post(`http://localhost:5000/api/posts/upvote/reply/id/${id}`)
.then(res => {
// console.log(res.data.data[0].comments[0])
console.log(res)
// ...item,
// const {posts} = this.state
// posts.push(res.data)
// this.setState({posts})
})
}
catch (err) {
console.log(err)
}
return {
...item,
// voted: true,
points: item.points + 1
}
}
return item
})
return {
replies: updatedReplies
}
})
// console.log('boops')
}
A little more context code which might help:
const replies = this.state.replies.slice().map((item, i) =>
<div
key={i}
className='replyItem'
>
<Reply
// key={i}
reply={item.reply}
id={item._id}
user_id={item.user_id}
createdAt={item.createdAt}
points={item.points}
handleDelete={() => this.handleDelete(item._id)}
user={this.props.auth}
handleReplyUpvote={() => this.handleReplyUpvote(item._id)}
// handleDownvote={() => this.handleReplyDownvote(item._id.points)}
/>
</div>
)
You are mixing async/await, promises and callbacks. Use either promises or asyns/await, not all. I have fixed few things and it should work. (I didn't test it though)
router.post("/upvote/reply/id/:id", async (req, res) => {
try {
const result = await Posts.findOneAndUpdate(
{ "comments._id": mongoose.Types.ObjectId(req.params.id) },
{
$inc: { "comments.$.points": 1 },
$push: { "comments.$.upvotedBy": req.user._id },
$pull: { "comments.$.downvotedBy": req.user._id },
}
);
return res.status(200).json({
success: true,
data: result,
});
} catch (error) {
return res.status(404).json({
success: false,
error: error.message,
message: "Post not upvoted!",
});
}
});
handleReplyUpvote = async(id) => {
const updatedReplies = [];
for(const item of this.state.replies){
if(item._id === id){
try{
const response = await axios
.post(`http://localhost:5000/api/posts/upvote/reply/id/${id}`)
console.log(response.data);
}catch(error){
console.log(error.message);
}
updatedReplies.push({
...item,
points: item.points + 1;
})
continue;
}
updatedReplies.push(item);
}
this.setState({
replies: updatedReplies
})
}
I have wrote a simple Update function. Its working fine for some minutes and then again its not working. Where I am going wrong? Please help me. I use PUT as my method.
code
accept = (req, res) => {
this._model.update({
user: new mongoose.Types.ObjectId(req.params.uid)
}, {
$set: {
status: 'active'
}
}, (err, obj) => {
if (err || !obj) {
res.send(err);
} else {
res.send(obj);
}
});
}
Model
{
"_id":"5d3189a00789e24a23438a0d",
"status":"pending",
"user":ObjectId("5d3189a00789e24a23438a0d"),
"code":"CT-123-345-234-233-423344",
"created_Date":"2019-07-19T09:13:04.297Z",
"updated_Date":"2019-07-19T09:13:04.297Z",
"__v":0
}
Request
api.abc.com/api/accept/5d3189a00789e24a23438a0d
Sometime it is returing values and sometime null.
You can use the following code to ensure the model is tied to a connection. This could be an issue of connection to the database.
const config = require('./config');
console.log('config.database.url', config.database.url);
return mongoose.createConnection(config.database.url, {
useMongoClient: true
})
.then((connection) => {
// associate model with connection
User = connection.model('User', UserSchema);
const user = new User({
email: 'someuser#somedomain.com',
password: 'xxxxx'
});
const prom = user.update();
// Displays: 'promise: Promise { <pending> }'
console.log('promise:', prom);
return prom
.then((result) => {
// Don't see this output
console.log('result:', result);
})
.catch((error) => {
// Don't see this output either
console.log('error:', error);
});
})
.catch((error) => {
console.log(error);
});
I think you need to use promise or async/await, try this
accept = async (req, res) => {
try {
const result = await this._model.update({
user: new mongoose.Types.ObjectId(req.params.uid)
}, {
$set: {
status: 'active'
}
});
return res.send(result);
} catch (e) {
return res.send(e);
}
};
I am following this graphql tutorial, everything was going ok until I try to use dataloaders.
My server.js is:
const start = async () => {
const mongo = await connectMongo();
const buildOptions = async req => {
const user = await authenticate(req, mongo.Users);
return {
context: {
dataloaders: buildDataloaders(mongo),
mongo,
user
},
schema
};
};
app.use('/graphql', bodyParser.json(), graphqlExpress(buildOptions));
app.use(
'/graphiql',
graphiqlExpress({
endpointURL: '/graphql',
passHeader: `'Authorization': 'bearer token-name#email.com'`
})
);
app.use('/', expressStaticGzip('dist'));
app.use('/attendance', expressStaticGzip('dist'));
app.use('/login', expressStaticGzip('dist'));
spdy.createServer(sslOptions, app).listen(process.env.PORT || 8080, error => {
if (error) {
console.error(error);
return process.exit(1);
} else {
console.info(
`App available at https://localhost:${process.env.PORT || 3000}`
);
}
});
};
My copy and paste dataloaders.js:
const DataLoader = require('dataloader');
async function batchUsers(Users, keys) {
return await Users.find({ _id: { $in: keys } }).toArray();
}
module.exports = ({ Users }) => ({
userLoader: new DataLoader(keys => batchUsers(Users, keys), {
cacheKeyFn: key => key.toString()
})
});
And my resolvers.js:
export default {
Query: {
allLinks: async (root, data, { mongo: { Links } }) =>
Links.find({}).toArray()
},
Mutation: {
createLink: async (root, data, { mongo: { Links }, user }) => {
const newLink = Object.assign({ postedById: user && user._id }, data);
const response = await Links.insert(newLink);
return Object.assign({ id: response.insertedIds[0] }, newLink);
},
createUser: async (root, data, { mongo: { Users } }) => {
const newUser = {
name: data.name,
email: data.authProvider.email.email,
password: data.authProvider.email.password
};
const response = await Users.insert(newUser);
return Object.assign({ id: response.insertedIds[0] }, newUser);
},
signinUser: async (root, data, { mongo: { Users } }) => {
const user = await Users.findOne({ email: data.email.email });
if (data.email.password === user.password) {
return { token: `token-${user.email}`, user };
}
}
},
Link: {
id: root => root._id || root.id,
postedBy: async ({ postedById }, data, { dataloaders: { userLoader } }) => {
return await userLoader.load(postedById);
}
},
User: {
id: root => root._id || root.id
}
};
When I try get my allLinks I got the error:
TypeError: The loader.load() function must be called with a value,but
got: undefined.
Can anyone help me?
So I was able to reproduce the error by creating a link with a user, deleting the user from the Mongo database, and then querying for the postedBy attribute of the Link.
I would suggest dropping all your links and recreating your user (register + sign in), creating a new link, then querying for the postedBy field.