admin管理员组文章数量:1327803
I'm creating a CronJob that calls an API and store its response in the database:
const CronJob = require("cron").CronJob;
const btc_price_ticker = require("../../controllers/BtcExchange/Ticker");
const currency = require("../../controllers/Currencies/CurrenciesController");
module.exports = new CronJob("* * * * * *", async function() {
const {
ticker: { sell }
} = await btc_price_ticker.getBtcPrice();
currency
.update({
params: {
id: "5cbdf078f5bcec257fcec792"
},
body: {
exchange_rate: sell,
lastUpdate: Date.now()
}
})
.catch(error => console.log(error));
});
It works fine, however I receive a TypeError: Cannot read property 'json' of undefined
I'm using the same function to update the database I use when updating by my API:
module.exports = {
async update(req, res) {
const currency = await Currency.findByIdAndUpdate(req.params.id, req.body, {
new: true
});
return res.json(currency);
}
};
The TypeError
happens in the return res.json(currency)
, and it only happens when it's called by the CronJob. When I put new information by API, it doesn't show any error.
I think it happens because when I call the function in CronJob
, I just pass the req
by parameter, but I don't know how to solve it. What am I supposed to do?
Thanks in advance!
I'm creating a CronJob that calls an API and store its response in the database:
const CronJob = require("cron").CronJob;
const btc_price_ticker = require("../../controllers/BtcExchange/Ticker");
const currency = require("../../controllers/Currencies/CurrenciesController");
module.exports = new CronJob("* * * * * *", async function() {
const {
ticker: { sell }
} = await btc_price_ticker.getBtcPrice();
currency
.update({
params: {
id: "5cbdf078f5bcec257fcec792"
},
body: {
exchange_rate: sell,
lastUpdate: Date.now()
}
})
.catch(error => console.log(error));
});
It works fine, however I receive a TypeError: Cannot read property 'json' of undefined
I'm using the same function to update the database I use when updating by my API:
module.exports = {
async update(req, res) {
const currency = await Currency.findByIdAndUpdate(req.params.id, req.body, {
new: true
});
return res.json(currency);
}
};
The TypeError
happens in the return res.json(currency)
, and it only happens when it's called by the CronJob. When I put new information by API, it doesn't show any error.
I think it happens because when I call the function in CronJob
, I just pass the req
by parameter, but I don't know how to solve it. What am I supposed to do?
Thanks in advance!
Share Improve this question asked Apr 22, 2019 at 17:48 Otavio BonderOtavio Bonder 1,9995 gold badges22 silver badges38 bronze badges 7- do you have express using bodyparser – Len Joseph Commented Apr 22, 2019 at 17:49
-
You're calling
update()
without passing the response object as the second argument – Nir Alfasi Commented Apr 22, 2019 at 17:51 - Yes @alfasin, you are right. I'm pretty sure this is the error, but I don't know what should I pass as the response object – Otavio Bonder Commented Apr 22, 2019 at 17:52
-
@OtavioBonder Ideally you should simply call
Currency.findByIdAndUpdate
or any other mon util function in the Corn rather than mockingreq
andres
– priyansh gupta Commented Apr 22, 2019 at 18:04 - If you're using cron-job, why do you need req/res from the first place? – Nir Alfasi Commented Apr 22, 2019 at 18:21
3 Answers
Reset to default 3There's a famous saying which says that you can solve almost any problem in CS by adding another layer of indirection. This is one of those cases:
Instead of of declaring your module as:
module.exports = {
async update(req, res) {
const currency = await Currency.findByIdAndUpdate(req.params.id, req.body, {
new: true
});
return res.json(currency);
}
};
Separate the logic from the route-logic:
module.exports = {
async getCurrency(id, params) {
const currency = await Currency.findByIdAndUpdate(id, params, {
new: true
});
return currency;
}
async update(req, res) {
const currency = await getCurrency(req.params.id, req.body);
return res.json(currency);
}
};
Now the route can call update()
and the cron-job can call getCurrency()
directly.
Ok, maybe my approach isn't the best, but since I'm passing an undefined object to update()
, and I don't need the response, I edited the update
function:
async update(req, res) {
const currency = await Currency.findByIdAndUpdate(req.params.id, req.body, {
new: true
});
if (res !== undefined) {
return res.json(currency);
}
}
So, since res is undefined, it doesn't return anything.
It's because both req
and res
is undefined
(or atleast not the proper request
and response
object) when the route is not requested by client (which is the case here).
Simplest solution I can think of is mock (or make an actual call) a client call in your cron
job by using modules like axios
, request
, request-promise
(with Promise
wrapper on top of request) like:
const rp = require('request-promise')
module.exports = new CronJob("* * * * * *", async function() {
try {
const {
ticker: { sell }
} = await btc_price_ticker.getBtcPrice();
// assuming your server is running in localhost, port 3000 and route is 'myapi/:id'
const url = "http://localhost:3000/myapi/5cbdf078f5bcec257fcec792";
const options = {
method: 'GET',
uri : url,
json: true,
body: {
exchange_rate: sell,
lastUpdate: Date.now()
}
}
const response = await rp(url);
} catch(error) {
console.log(error);
}
});
Since you can execute the db
methods, a simpler alternative would be to directly execute Currency.findByIdAndUpdate
in your cron
job. I don't see any reason why you would want to call your route
in your code.
本文标签: javascriptNodeJS TypeError Cannot read property 39json39 of undefinedStack Overflow
版权声明:本文标题:javascript - NodeJS: TypeError: Cannot read property 'json' of undefined - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742234525a2437830.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论