Get inserted document directly in RethinkDB - database

I have been starting with RethinkDB. I have gone through the documentation. I have a simple use case of returning the inserted document when a POST call is made. This is something I have done so far.
router.post('/user', jsonParser, async (req: Request, res: Response) => {
const connection = await conn;
const { name, email, employeeId } = req.body;
// Email is primary key
consumerTable.insert({
name,
email,
employeeId,
}).run(connection, (err: any, result: any) => {
if (err) {
throw err;
} else {
consumerTable.get(email).run(connection, (innerErr: any, userResult: any) => {
if(innerErr) {
throw innerErr;
} else {
res.send({
data: {
...userResult
},
responseCode: 200,
});
}
});
}
});
});
Is there any way to get the inserted object in the insert result itself. I read a lot of documentation, but didn't find anything useful.
Any help would be great. Cheers!

You may use the returnChanges option of the insert command as specified in the documentation. It should look like this:
consumerTable.insert({
name,
email,
employeeId,
}, { returnChanges: true }).run(connection, async (err: any, cursor: any) => {
const data = await cursor.toArray();
// .error should be undefined, unless... an error happened!
// not sure about the format though, console.log data to check it really is an array
res.send({ data: data[0].new_val, error: data[0].error });
});

Related

I am getting error while updateQueryData in rtk query, how do I fix this?

I am new to react query and tried many tutorials still I am not logging anything and nothing happens after the following code, cannot even log new data, It doesnt feel like there is any error. POST is working perfectly.
addCategory: builder.mutation({
query: (body) => ({
method: "POST",
url: apiLinks.categoryPUT,
body: body,
}),
async onQueryStarted(body, { dispatch, queryFulfilled }) {
try {
const res = await queryFulfilled;
const id = _.get(res, "data.data.InsertedID", Date.now());
dispatch(
categoryApi.util.updateQueryData(
"getAllCategory",
undefined,
(data) => {
const newBody = { id, ...body };
console.log({ data, newBody }); //nothing shows here
data.push(newBody);
}
)
);
} catch (error) {
console.log({ error }); // nothing logs here
}
},
}),
problem was I used this: useGetAllCategoryQuery("getAllCat"); to fetch data.
useGetAllCategoryQuery("getAllCat");
so it should be:
categoryApi.util.updateQueryData(
"getAllCategory",
"getAllCat", //change here
seems its a unique identifier for cache data

Creating GraphQL Search query using React Native

I am trying to implement a search query to help me search by name or category. I need help with only the backend part of it which is setting up the resolver and the index which im not sure if I m doing it right
Resolver.js
//search for single user
user: async ({_id}) => {
try {
const foundUser = await User.findOne({_id: _id})
return foundUser;
} catch (err){
throw err;
}
},
//search for all users
users: async () => {
try{
const users = await User.find()
return users;
} catch(err) {
throw err;
}
},
I want to be able to search all users with the role "Star" and do the search only on those users. Not really sure where to go from here
Index.js
type User {
_id: ID!
username: String
password: String
name: String
role: String
enterCategory: String
}
//not sure if search is right
type RootQuery {
user(_id: ID!): User!
users: [User!]!
searchStars(search: String): [Users]!
}
Index.js
searchCategories(search: String): [User]!
Resolver
searchCategories: async ({ search }) => {
try {
const users = await User.find()
return users.filter(x => x.enterCat === search);
} catch (err) {
throw err;
}
}

Call a function after react-redux dispatch has finished

So I have here a form which which when submitted, calls this function:
const handleSubmit = (e) => {
e.preventDefault();
try {
dispatch(addCategory({ category, identifier, definition }));
} catch (err) {
console.log(err.message);
}
};
and this is the code to my addCategory action in a separate file.
export const addCategory =
({ category, identifier, definition }) =>
async (dispatch) => {
try {
const { data } = await axios.post(
"http://localhost:5000/Admin/addCategory",
{ category, identifier, definition }
);
dispatch({ type: "ADD_CATEG", payload: data });
} catch (error) {
dispatch({
type: "GET_ERROR",
payload: error.response.data.errorMessage,
});
}
};
As you can see, I have an error handling in my backend and it triggers when the user inputs a duplicate data. The way I am getting that error is through this:
const { error } = useSelector((state) => state.categories);
What I want is that after I dispatch my action in my handleSubmit, it checks whether the error is empty or not. I've tried to call a function after the try-catch block in handleSubmit which looks like this. I've tried to run it then I've entered correct inputs of data without error, it displays 'no err' but if I tried to enter a duplicate input, it doesn't give me an error but in my redux console, it is already there. When I submit the form again, then it will now display the 'with err'. I've been trying to figure it out but can't seem to find any solutions.
const try = () => {
if (error !== null) {
console.log("with err");
} else if (error === null) {
console.log("no err");
}
};
I've ran into this problem as well.
One is catching an error on the request being sent
The other is catching an error from data handling on the Redux side
This is a pattern I've used before, you just need to make sure you are handling errors at every level.
export const addCategory =
({ category, identifier, definition }) =>
async (dispatch) => {
let response
try {
response = await axios.post(
"http://localhost:5000/Admin/addCategory",
{ category, identifier, definition }
);
dispatch({ type: "ADD_CATEG", payload: data });
} catch (error) {
response =
dispatch({
type: "GET_ERROR",
payload: error.response.data.errorMessage,
});
}
if(response?.data){
// do stuff for success
}
// do stuff for errors
};

Why is res.json returning empty?

When I make a "GET" request from the client to the server the server should make a axios.get() call to a stock API to retrieve data for an array of tickers. When I console.log the results it seems to be working fine but the array doesn't seem to save, like it gets wiped out and comes back to the client as empty. I think I might be messing this up with async/await.
async function currentPrice(ticker) {
const apiURL = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${ticker}&apikey=${API_KEY}`;
let price;
await axios.get(apiURL).then(data => {
try {
price = data.data["Global Quote"]["05. price"];
} catch (error) {
console.log(error)
}
})
return price;
};
app.get("/refresh", redirectLogin, (req, res) => {
const {
user
} = res.locals;
var array = [];
connection.query(`SELECT * FROM holdings WHERE user_name = '${user.user_name}' AND quantity > 0`, (err, results) => {
if (err) throw err;
results.forEach(holding => {
currentPrice(holding.ticker).then(data => {
var updatedTicker = {
ticker: holding.ticker,
description: holding.description,
price_acquired: holding.price_acquired,
market_price: data,
delta: parseFloat(this.market_price) - parseFloat(this.price_acquired),
quantity: holding.quantity,
trade_date: holding.date_acquired
}
array.push(updatedTicker);
// console.log(array);
console.log(updatedTicker.market_price)
})
})
res.json(array)
})
})
You are calling res.json(array) before any of your currentPrice().then(...) calls have finished, thus the array is still empty.
There are a number of different ways to solve this. Probably the simplest is to change for .forEach() loop to a plain for loop and then use async/await to serialize each of your calls to currentPrice():
function currentPrice(ticker) {
const apiURL = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${ticker}&apikey=${API_KEY}`;
return axios.get(apiURL).then(data => {
try {
return data.data["Global Quote"]["05. price"];
}
catch (error) {
console.log(error);
throw error;
}
});
}
app.get("/refresh", redirectLogin, (req, res) => {
const { user } = res.locals;
connection.query(`SELECT * FROM holdings WHERE user_name = '${user.user_name}' AND quantity > 0`, async (err, results) => {
if (err) {
console.log(err);
res.sendStatus(500);
return;
}
try {
const array = [];
for (let holding of results) {
let data = await currentPrice(holding.ticker);
let updatedTicker = {
ticker: holding.ticker,
description: holding.description,
price_acquired: holding.price_acquired,
market_price: data,
delta: parseFloat(this.market_price) - parseFloat(this.price_acquired),
quantity: holding.quantity,
trade_date: holding.date_acquired
}
array.push(updatedTicker);
}
res.json(array);
} catch(e) {
console.log(e);
res.sendStatus(500);
}
});
});
Various changes:
Simplified the currentPrice() function to just return the axios promise directly
Appropriately reject in currentPrice() if there's an error so the caller sees the error.
Add proper error handling (sending an error response), if the db query fails.
Switch .forEach() loop to a for loop so we can use await to serialize the calls to currentPrice() so we can more easily know when they are all done.
Add error handling and sending of an error response if currentPrice() has an error.
Call res.json(array) only after all the now-serialized calls to await currentPrice() have completed.
FYI, a fully complete transformation here would switch to mysql2 so you can use the promise interface for connection.query() rather than the plain callback interface that you are using now. That would allow you to consolidate error handling to one place more easily.

mongoose findOne method is returning null

I am following this tutorial. Even though code is exactly what is mentioned in the tutorial, every time i run the graphql mutation query to update a particular tweet, it returns null and logs null on cmd.
I verified mongoose version is same (4.11.3).I believe something is wrong with findOne method as even in deleteTweet resolver, findOne is returning null. Is it because findOne needs a callback? but in the tutorial there is no callback passed. I also noticed that findOneAndUpdate works fine but it creates a new entry rather updating the existing tweet.
updateTweet: async (_, { id, ...rest}, { user }) => {
try {
await requireAuth(user)
const tweet = await Tweet.findOne({ id, user: user.id });
console.log(tweet);
if(!tweet) {
throw new Error('Not Found!');
}
return tweet.save();
} catch (e) {
throw e;
}
},
deleteTweet: async (_, { id }, { user }) => {
try {
await requireAuth(user);
const tweet = await Tweet.findOne({ id, user: user.id });
if(!tweet) {
throw new Error('Not Found !')
}
await tweet.remove();
return {
message: "Deleted Tweet Successfully"
}
}catch(error) {
throw error;
}
}
}
TweetSchema
import mongoose, { Schema } from 'mongoose';
const TweetSchema = new Schema({
text: {
type: String,
minlength: [5, 'Text need to be longer'],
maxlength: [144, 'Text is too long'],
},
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
favoriteCount: {
type: Number,
default: 0
}
}, { timestamps: true})
export default mongoose.model('Tweet', TweetSchema);
You have a typo. In MongoDB, the key field is _id NOT id. This is added automatically by MongoDB unless provided, so you need to change your code to use _id instead.

Resources