无法从函数内更新 Meteor 中的 Mongo 集合
Can't update Mongo Collection in Meteor from within a function
我在应用程序的 imports/api 中设置了一个 webhook。这是一个 Stripe webhook,我正在尝试更新 Campaign 集合。我正在使用 Meteor 方法进行此调用,但没有任何反应。如果我将调用添加回它,我不会收到任何错误或结果。但是,如果我采用相同的 Meteor 方法并将其包含在服务器上的 main.js 中的 Meteor 启动函数中,它 运行 没问题。我也试过只使用集合的更新功能,但它也不起作用。 Main.js 包含这个文件,我不明白为什么这不起作用也不会出现错误。这行最重要的部分是底部的 Paid == true,这就是逻辑所在。控制台会吐出信息,但方法不会运行。可能是什么问题?
import bodyParser from 'body-parser';
import { Picker } from 'meteor/meteorhacks:picker';
import {Campaign} from '../api/campaigns';
let campaignID;
let chargeAmount;
let chargeID;
let hasPaid = false;
//This will run outside the updateCampaign function fine and works as expected
Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "555"}});
function updateCampaign(){
//these consoles will print and prove the function runs
console.log('campaignID type:' + campaignID)
console.log('chargeIDtype:' + chargeID)
console.log('amount type:' + chargeAmount)
//doesn't work even with strings prefilled
Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
//This didn't run either but would run outside of this function
Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID, (err, result) => {
if (err){
console.log('error')
}
});
}
// Middleware declaration
Picker.middleware(bodyParser.json({
limit: '10MB',
verify: function(req,res,buf) {
var url = req.originalUrl;
if (url.startsWith('/webhook')) {
req.rawBody = buf.toString();
let newResponse = req.rawBody;
//stripe returns to 2 objects, this makes it two arrays to parse it
let parsedResponse = JSON.parse('[' + newResponse.replace(/}{/g, '},{') + ']');
parsedResponse = parsedResponse[0].data.object;
//break down two further objects
if (parsedResponse.object == "charge"){
chargeID = parsedResponse.id;
hasPaid = parsedResponse.paid;
chargeAmount = parsedResponse.amount / 100;
}
else if (parsedResponse.object == "checkout.session"){
let campaignIDArray = parsedResponse.success_url.split('/');
campaignID = campaignIDArray[5];
}
// If user has paid, update campaign
if (hasPaid == true && chargeID && campaignID && chargeAmount){
console.log(hasPaid, chargeID, campaignID, chargeAmount)
//
updateCampaign();
}
}
}
}));
在当前 Meteor 环境之外(例如在回调函数或中间件处理程序中)对需要 Meteor 环境的构造的任何调用都将使用 Meteor 环境进行绑定。
在您的情况下,这似乎是 updateCampaign
,因为它会调用 Meteor-Mongo 集合:
const updateCampaign = Meteor.bindEnvironment(function () {
const updated = Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
const callResult = Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID);
})
另请注意,此函数中的集合在异步模式下 运行,并且只有在 Meteor 环境代码中,您才能以同步方式编写代码并让它处理异步。您始终可以使用 async/await
:
"wait" 获得结果
function async updateCampaign(){
const updated = await Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
//This didn't run either but would run outside of this function
const callResult = await Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID);
}
或者你使用Promise.await
,如果你想避免async/await
:
function updateCampaign(){
const updated = Promise.await(Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}}))
//This didn't run either but would run outside of this function
const callResult = Promise.await(Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID))
}
读数:
https://guide.meteor.com/using-npm-packages.html#bind-environment
https://docs.meteor.com/api/methods.html#Meteor-call
https://guide.meteor.com/using-npm-packages.html#promises
https://github.com/meteor/meteor/tree/devel/packages/promise
我在应用程序的 imports/api 中设置了一个 webhook。这是一个 Stripe webhook,我正在尝试更新 Campaign 集合。我正在使用 Meteor 方法进行此调用,但没有任何反应。如果我将调用添加回它,我不会收到任何错误或结果。但是,如果我采用相同的 Meteor 方法并将其包含在服务器上的 main.js 中的 Meteor 启动函数中,它 运行 没问题。我也试过只使用集合的更新功能,但它也不起作用。 Main.js 包含这个文件,我不明白为什么这不起作用也不会出现错误。这行最重要的部分是底部的 Paid == true,这就是逻辑所在。控制台会吐出信息,但方法不会运行。可能是什么问题?
import bodyParser from 'body-parser';
import { Picker } from 'meteor/meteorhacks:picker';
import {Campaign} from '../api/campaigns';
let campaignID;
let chargeAmount;
let chargeID;
let hasPaid = false;
//This will run outside the updateCampaign function fine and works as expected
Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "555"}});
function updateCampaign(){
//these consoles will print and prove the function runs
console.log('campaignID type:' + campaignID)
console.log('chargeIDtype:' + chargeID)
console.log('amount type:' + chargeAmount)
//doesn't work even with strings prefilled
Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
//This didn't run either but would run outside of this function
Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID, (err, result) => {
if (err){
console.log('error')
}
});
}
// Middleware declaration
Picker.middleware(bodyParser.json({
limit: '10MB',
verify: function(req,res,buf) {
var url = req.originalUrl;
if (url.startsWith('/webhook')) {
req.rawBody = buf.toString();
let newResponse = req.rawBody;
//stripe returns to 2 objects, this makes it two arrays to parse it
let parsedResponse = JSON.parse('[' + newResponse.replace(/}{/g, '},{') + ']');
parsedResponse = parsedResponse[0].data.object;
//break down two further objects
if (parsedResponse.object == "charge"){
chargeID = parsedResponse.id;
hasPaid = parsedResponse.paid;
chargeAmount = parsedResponse.amount / 100;
}
else if (parsedResponse.object == "checkout.session"){
let campaignIDArray = parsedResponse.success_url.split('/');
campaignID = campaignIDArray[5];
}
// If user has paid, update campaign
if (hasPaid == true && chargeID && campaignID && chargeAmount){
console.log(hasPaid, chargeID, campaignID, chargeAmount)
//
updateCampaign();
}
}
}
}));
在当前 Meteor 环境之外(例如在回调函数或中间件处理程序中)对需要 Meteor 环境的构造的任何调用都将使用 Meteor 环境进行绑定。
在您的情况下,这似乎是 updateCampaign
,因为它会调用 Meteor-Mongo 集合:
const updateCampaign = Meteor.bindEnvironment(function () {
const updated = Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
const callResult = Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID);
})
另请注意,此函数中的集合在异步模式下 运行,并且只有在 Meteor 环境代码中,您才能以同步方式编写代码并让它处理异步。您始终可以使用 async/await
:
function async updateCampaign(){
const updated = await Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}});
//This didn't run either but would run outside of this function
const callResult = await Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID);
}
或者你使用Promise.await
,如果你想避免async/await
:
function updateCampaign(){
const updated = Promise.await(Campaign.update({_id: "BAxBhk4ae3AdHxxEQ"}, {$set: {chargeTrx: "chargeID", amount: "333"}}))
//This didn't run either but would run outside of this function
const callResult = Promise.await(Meteor.call("updateCampaignForPayment", campaignID, chargeAmount, chargeID))
}
读数:
https://guide.meteor.com/using-npm-packages.html#bind-environment
https://docs.meteor.com/api/methods.html#Meteor-call
https://guide.meteor.com/using-npm-packages.html#promises
https://github.com/meteor/meteor/tree/devel/packages/promise