How to find documents in array in mongoose - node.js

How can i use mongoose.find() method to find the below code.
Paid.find({info:{data:"status"}})
This is not working as it is returning empty array
info{
event: 'charge.success',
data: {
id: 1190118808,
domain: 'test',
status: 'success',
reference: 'T458573232919212',
amount: 100000,
message: null,
gateway_response: 'Successful',
paid_at: '2021-06-26T00:25:33.000Z',
created_at: '2021-06-26T00:25:24.000Z',
}

If you use mongoose, it should be as easy as doing YourModel.find({ data: { status: "success" } }), this is assuming info is not an actual property on the document
Full Example (including data structure (the Schema), simplified):
const schema1 = new mongoose.Schema({
data: {
status: String
}
});
const model1 = mongoose.model("model1", schema1);
(async () => {
// connect the connection before this part
await model1.create({ data: { status: "success" } });
await model1.create({ data: { status: "failure" } });
// this should only find & log the "success" one in the array
const found = await model1.find({ data: { status: "success" } }).exec();
console.log("found", found);
})()

Related

NodeJS Array not filling up

Im using mongodb as a database after getting the valuation data which are more then one , i loop inside them and get the offers according to the offres_id , I asure you that the database has data inside and to querys are working correctly in fact if i console log them in each iteration i get this result
{
offre: [
{
_id: new ObjectId("63320bf87123db5691c51392"),
user_id: '63304e44aa63c519d887dac1',
brand: 'HP',
model: 'AZGGH-89855A',
photo: '16642242480661659650294043-bs-5.png',
scan_method: 'manual',
__v: 0
}
],
valuation: {
_id: new ObjectId("63320d39a5677df3cebcbdae"),
user_id: '63304e44aa63c519d887dac1',
offre_id: '63320bf87123db5691c51392',
given_price: '1236',
comment: 'no comment',
__v: 0
}
}
{
offre: [
{
_id: new ObjectId("6334202a8c7e6d90b35ee999"),
user_id: '63304e44aa63c519d887dac1',
brand: 'DELL',
model: 'AZGGH-89855A',
photo: '1664360490280Capture.PNG',
scan_method: 'manual',
__v: 0
}
],
valuation: {
_id: new ObjectId("633420be8c7e6d90b35ee99e"),
user_id: '63304e44aa63c519d887dac1',
offre_id: '6334202a8c7e6d90b35ee999',
__v: 0
}
}
but when i try storing each offre & valuation at the same array cell and return it i get this as a result
[]
However this is the code
router.get('/get', async (req, res) => {
try {
Valuation.find({ user_id: req.session.userID })
.exec()
.then(valuation => {
let myData = [];
if (valuation) {
for (let i = 0; i < valuation.length; i++) {
Offre.find({_id : valuation[i].offre_id})
.exec()
.then(offre=>{
myData.push({offre : offre, valuation : valuation[i]})
})
}
res.status(200).json(myData)
} else {
res.status(404).json('no valuations found')
}
})
.catch(error => {
res.status(500).json(error.message)
})
} catch (error) {
res.status(500).json({ error: error.message })
}
})
Since you're already using async, it would be a shame to not use await to simplify your code:
router.get("/get", async (req, res) => {
try {
const valuation = await Valuation.find({ user_id: req.session.userID }).exec();
if (valuation) {
let myData = [];
for (let i = 0; i < valuation.length; i++) {
const offre = await Offre.find({ _id: valuation[i].offre_id }).exec();
myData.push({ offre: offre, valuation: valuation[i] });
}
res.status(200).json(myData);
} else {
res.status(404).json("no valuations found");
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
You can probably also speed up the Offre query by using an $in query to retrieve all offres with one query, but that's another thing.

Automate NodeJS Express Get and Post request using Cron

I have an existing get and post request from database which is:
router.post('/stackExample', async (req, res) => {
try {
//MAKE GET REQUEST FROM MONGODB
const stackCron = await Borrower.aggregate([
{ $unwind: { path: "$application", preserveNullAndEmptyArrays: true } },
{
$project: {
'branch': '$branch',
'status': '$application.status',
},
},
{ $match: { status: 'Active' } },
]);
//MAKE POST REQUEST TO MONGODB
for (let k = 0; k < stackCron.length; k++) {
const branch = stackCron[k].branch;
const status = stackCron[k].status;
const lrInterest = await Financial.updateOne({ accountName: 'Processing Fee Income'},
{
$push:
{
"transactions":
{
type: 'Credit',
firstName: 'SysGen',
lastName: 'SysGen2',
amount: 100,
date: new Date(),
}
}
})
}
res.json({ success: true, message: "Success" });
} catch (err) { res.json({ success: false, message: 'An error occured' }); }
});
This code works fine if request is made using the client but I want to automate this via cron:
Here is what I did:
var CronJob = require('cron').CronJob;
var job = new CronJob('* * * * * *', function () {
makeRequest()
}, null, true, 'America/Los_Angeles');
job.start();
function makeRequest(message){
//Copy-paste entire router post request.
}
There seems to be no response if I copy-paste my code in the function. What have I missed?
There is no response from a cron job because there is no request coming to your makeRequest function. That makes sense because a cron job is independent of any incoming requests.
One other reason, you might not be getting any data from your updateOne operation is that it doesn't return the updated document. It returns the status of that operation instead. Take a look here. If you want to get the updated document you might want to use findOneAndUpdate.
const response = await Todo.findOneAndUpdate(
{ _id: "a1s2d3f4f4d3s2a1s2d3f4" },
{ title: "Get Groceries" },
{ new: true }
);
// response will have updated document
// We won't need this here. This is just to tell you how to get the updated document without making another database query explicitly
The body of your router function is performing an async/await operation. But you didn't specify the makeRequest function to be async. This could also be the issue.
cron job will update the database but if you want to get the updated documents, you'll have to make a GET call to the server and define a new route, with required parameters/query.
Your makeRequest function will look something like this
async function makeRequest() {
try {
//MAKE GET REQUEST FROM MONGODB
const stackCron = await Borrower.aggregate([
{ $unwind: { path: "$application", preserveNullAndEmptyArrays: true } },
{
$project: {
branch: "$branch",
status: "$application.status",
},
},
{ $match: { status: "Active" } },
]);
//MAKE POST REQUEST TO MONGODB
for (let k = 0; k < stackCron.length; k++) {
const branch = stackCron[k].branch;
const status = stackCron[k].status;
const lrInterest = await Financial.updateOne(
{ accountName: "Processing Fee Income" },
{
$push: {
transactions: {
type: "Credit",
firstName: "SysGen",
lastName: "SysGen2",
amount: 100,
date: new Date(),
},
},
}
);
}
/**
* Write to a log file if you want to keep the record of this operation
*/
} catch (err) {
/**
* Similarly write the error to the same log file as well.
*/
}
}
In your cron job
var job = new CronJob(
"* * * * * *",
async function () {
await makeRequest();
},
null,
true,
"America/Los_Angeles"
);
Your new route
router.get("/stack/:accountName", async (req, res, next) => {
const { accountName } = req.params;
try {
const financial = await Financial.find({ accountName });
res.status(200).json({ message: "success", data: financial });
} catch (err) {
res.status(500).json({ message: "error", reason: err.message });
}
});
Simply call it as
fetch(
`http://example.net/stack/${encodeURIComponent("Processing Fee Income")}`,
{ method: "GET" }
);

How to figure out stripe issue for payout / transfer with Strapi

I am going to implement transfer and payout functional with stripe between accounts using node js.
But I met one issue to implement this one.
Code:
const stripe = require('stripe')('****');
try {
cardInfo = await PayInfo.findOne({user_id: uid});
if (!cardInfo ) {
return ctx.badRequest(
null,
formatError({
id: 'PayInfo.create.findByUserId.error',
message: 'User is not available',
})
);
}
let targetId = cardInfo.account_id;
let payoutState = null;
try {
const payoutState = await stripe.transfers.create({
amount: 400,
currency: 'usd',
destination: targetId,
source_type: 'bank_account',
});
await record.create({
order_id: id,
user_id: user.id,
payment_id: payoutState.id,
transaction: 'transfer',
amount: 400,
state: payoutState.reversed ? 'failed' : 'succeeded',
});
} catch (error) {
return ctx.send(null, {
error,
payoutState,
});
}
} catch (e) {
return ctx.badRequest(
null,
{
error: e,
}
);
}
But I met this issue message from it.
If I delete stripe integration part then it works well. - so wired.
{
actual: false
code: "ERR_ASSERTION"
expected: true
generatedMessage: false
operator: "=="
}
I am not sure what I was wrong, would you let me know on it please?
Thanks.

Correct boom error not being returned in hapijs v17

API controller:
export const addPaymentCard = async (request: ICustomerAddPaymentCardRequest, h: ResponseToolkit) => {
try {
const { _id: customerId } = request.auth.credentials
const { cardToken } = request.payload
const customerInfo: ICustomer | null = await Customer.findOne({ _id: customerId })
if (!customerInfo) throw Boom.notFound("Customer not found")
if (!customerInfo.stripeId) {
const stripeCustomer = await createStripeCustomer({ email: customerInfo.email, metadata: { customerId: customerId.toString() } })
await Customer.findOneAndUpdate({ _id: customerInfo._id }, { stripeId: stripeCustomer.id }, { new: true })
customerInfo["stripeId"] = stripeCustomer.id
}
const card = await createStripeSource(customerInfo.stripeId, { source: cardToken })
return h.response({ statusCode: 200, message: "Success", data: card })
} catch (error) {
logger.error(`${request.method.toUpperCase()} ${request.url.pathname}, error=${error}`)
throw error
}
}
Boom error is thrown in this method:
export const createStripeSource = async (customerId: string, data: Stripe.CustomerSourceCreateParams) => {
try {
const source = await stripe.customers.createSource(customerId, data)
return source
} catch (error) {
logger.error(`create stripe payment methods incurred error=${error}`)
throw error
}
}
Expected error to be sent: like invalid card
Actual error being sent: Internal Server error
How can I get actual error returned by stripe?
This is also happening with other methods that are returning error when called inside any handler.
node v12
#hapi/hapi v20
#hapi/boom v9

GraphQL with RESTful returning empty response

I am connecting GraphQL with REST endpoints, I confirmed that whenever I am calling http://localhost:3001/graphql it is hitting REST endpoint and it is returning JSON response to GraphQL server, but I am getting an empty response from GraphQL server to GUI as follows:
{
"data": {
"merchant": {
"id": null
}
}
}
Query (decoded manually):
http://localhost:3001/graphql?query={
merchant(id: 1) {
id
}
}
Below is how my GraphQLObjectType looks like:
const MerchantType = new GraphQLObjectType({
name: 'Merchant',
description: 'Merchant details',
fields : () => ({
id : {
type: GraphQLString // ,
// resolve: merchant => merchant.id
},
email: {type: GraphQLString}, // same name as field in REST response, so resolver is not requested
mobile: {type: GraphQLString}
})
});
const QueryType = new GraphQLObjectType({
name: 'Query',
description: 'The root of all... queries',
fields: () => ({
merchant: {
type: merchant.MerchantType,
args: {
id: {type: new GraphQLNonNull(GraphQLID)},
},
resolve: (root, args) => rest.fetchResponseByURL(`merchant/${args.id}/`)
},
}),
});
Response from REST endpoint (I also tried with single object in JSON instead of JSON array):
[
{
"merchant": {
"id": "1",
"email": "a#b.com",
"mobile": "1234567890"
}
}
]
REST call using node-fetch
function fetchResponseByURL(relativeURL) {
return fetch(`${config.BASE_URL}${relativeURL}`, {
method: 'GET',
headers: {
Accept: 'application/json',
}
})
.then(response => {
if (response.ok) {
return response.json();
}
})
.catch(error => { console.log('request failed', error); });
}
const rest = {
fetchResponseByURL
}
export default rest
GitHub: https://github.com/vishrantgupta/graphql
JSON endpoint (dummy): https://api.myjson.com/bins/8lwqk
Edit: Adding node.js tag, may be issue with promise object.
Your fetchResponseByURL function get empty string.
I think the main problem is that you are using wrong function to get the your JSON string, please try to install request-promise and use it to get your JSON string.
https://github.com/request/request-promise#readme
something like
var rp = require('request-promise');
function fetchResponseByURL(relativeURL) {
return rp('https://api.myjson.com/bins/8lwqk')
.then((html) => {
const data = JSON.parse(html)
return data.merchant
})
.catch((err) => console.error(err));
// .catch(error => { console.log('request failed', error); });
}
In this case using data.merchant solved my problem. But the above suggested solution i.e., use of JSON.parse(...) might not be the best practice because if there are no object in JSON, then expected response might be as follows:
{
"data": {
"merchant": null
}
}
Instead of fields to be null.
{
"data": {
"merchant": {
"id": null // even though merchant is null in JSON,
// I am getting a merchant object in response from GraphQL
}
}
}
I have updated my GitHub: https://github.com/vishrantgupta/graphql with working code.

Resources