this my code
in apollo clients I use useMutation.
apollo clients
const [addTodo, { loading, error, data }] = useMutation(gql);
apollo-server
Mutation: {
signUp: async (_, formSignUp, { models: { User }, res }) => {
try {
const user = new User(formSignUp);
await user.save();
const token = await user.generateAuthToken();
res.cookie("darkAmasia", token, {
httpOnly: true
});
return "string";
} catch (error) {
?????????
}
}
}
What should I write in catch ? to send a message {status:400,error:true}in useMutation error.
I heard that throw new ApolloError is used for these purposes.But I do not know how to do it.
Read more about error handling here
you can create your own Error class which extends ApolloError and pass status as default attribute.
Mutation: {
signUp: async (_, formSignUp, { models: { User }, res }) => {
try {
const user = new User(formSignUp);
await user.save();
const token = await user.generateAuthToken();
res.cookie("darkAmasia", token, {
httpOnly: true
});
return "string";
} catch (error) {
throw new ApolloError("Something went wrong", "BAD_INPUT",{status:400,error:true});
}
}
}
Related
Everything works fine, but the data I get in res() is one step behind. I rewrote the entire code a hundred times and no longer understand what the problem is
here is part of the code backend on express.js, node.js and mongodb:
export const addToCart = async (req, res) => { try {
const cart = await CartModul.findOne({ user: req.userId });
if (cart) {
const product_id = req.body.product_id;
const item = cart.cartItems.find((c) => c.product_id == product_id);
console.log("item", item);
if (item) {
try {
const cart = await CartModul.findOneAndUpdate(
{ user: req.userId, "cartItems.product_id": product_id },
{
"cartItems.$": {
...req.body,
quantity: item.quantity + req.body.quantity,
totalPrice: item.totalPrice + req.body.price,
},
}
);
if (cart) {
return res.status(200).json({ cart });
}
} catch (error) {
return res.status(400).json({ error });
}
} else {
try {
const cart = await CartModul.findOneAndUpdate(
{ user: req.userId },
{
$push: {
cartItems: req.body,
},
}
);
if (cart) {
return res.status(200).json({ cart });
}
} catch (error) {
return res.status(400).json({ error });
}
}
} else {
try {
const cart = new CartModul({
user: req.userId,
cartItems: req.body,
});
cart.save();
res.json(cart);
} catch (error) {
return res.status(400).json({ error });
}
} } catch (error) {
return res.status(400).json({ error })}};
In the else condition add await. i.e.
let newCart = await cart.save();
res.json(newCart);
Use {new: true) in findOneAndUpdate() and make async in moment with save()
When I console.log the variable refToken before the get request the refToken shows what it contains but after that nothing, and my backend sends me the error 401 which means no token was provided!!
I am really confused here
utility file for expo-secure-store
import * as SecureStore from 'expo-secure-store';
const saveRefreshToken = async (value: string) => {
try {
await SecureStore.setItemAsync("refreshToken", value);
} catch (e) {
console.log("Cannot set refresh token")
}
}
const getRefreshToken = async () => {
try {
return await SecureStore.getItemAsync("refreshToken");
} catch (e) {
console.log("can't get requested refreshToken", e);
}
}
const deleteRefreshToken = async () => {
try {
await SecureStore.deleteItemAsync("refreshToken");
} catch (e) {
console.log("cannot delete refreshToken ", e);
}
}
export default {
saveRefreshToken,
getRefreshToken,
deleteRefreshToken
};
React native code
import axios from "../api/axios";
import useAuth from "./useAuth";
import storage from "../utility/storage";
import jwtDecode from "jwt-decode";
const useRefreshToken = () => {
const {setAuth, auth} = useAuth();
return async () => {
const refToken = await storage.getRefreshToken();
// withCredentials: true,
const response = await axios.get(`/auth/refresh/`, {
params: {refreshToken: refToken},
});
//#ts-ignore
setAuth({user: jwtDecode(response.data.accessToken), accessToken: response.data.accessToken});
return response.data.accessToken;
};
}
export default useRefreshToken;
Node.js backend part that deals with this request
// TODO: Generate new access token from refresh
export const refreshTokenSignIn = (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
// const refreshToken = req.cookies.jwt;
const refreshToken = req.body.refreshToken;
try {
// Check if the refresh token is not null
if (!refreshToken)
return res.status(401).json({message: "No token provided!"});
// console.log(refreshToken);
const sql = `select * from token_records where refresh_token = '${refreshToken}'`;
// Check if there is such refresh token for the current user
db.query(
sql,
[refreshToken],
(err: QueryError, result: RowDataPacket[]) => {
if (err) return next(err);
if (result.length === 0)
return res.status(403).json({message: "You don't have access"});
//#ts-ignore
jwt.verify(
refreshToken,
//#ts-ignore
process.env.JWT_REFRESH_SECRET,
(err2: VerifyErrors, user: JwtPayload) => {
if (err2) return res.status(403).json({message: "You don't have access"});
const accessToken = jwt.sign(
{
user_id: user.user_id,
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
email: user.email,
role: user.role,
},
//#ts-ignore
process.env.JWT_SECRET
);
res.status(200).json({accessToken: accessToken});
next();
}
);
}
);
} catch (e) {
console.log(e);
next();
}
};
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
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 use the oracle-sage library. And when I want to delete a record, an error occurs.
{
"success": false,
"message": "User.destroy is not a function"
}
How can fix this?
const User = require('../models/User')
const errorHandler = require('../utils/errorHandler')
module.exports.remove = async function (req, res) {
try {
await User.destroy({
USER_ID: req.params.USER_ID
})
res.status(200).json({
message: 'User deleted.'
})
} catch (e) {
errorHandler(res, e)
}
}
Probably .destroy is not a static method, needs an instantiated object. You can try to get the user object first then destroy it.
try {
let user = await User.findOne({ USER_ID: req.params.USER_ID});
user.destroy().then(function(){
res.status(200).json({
message: 'User deleted.'
})
});
} catch (e) {
errorHandler(res, e)
}
Another way to implement destroy method is as below
const deleteUser = async (req,res) => {
console.log('Deleting User by Id')
const userId = await req.params.id
const user = await User.destroy({
where:{
id : userId
},
raw:true
}).catch(error=>console.log(error))