如何将环回 findById 方法的结果推送到 ctx.result
How to push the result from a loopback findById method into ctx.result
我能够从 findById 函数内部推送结果并且日志打印正确,但在 forEach 循环之外它只是空的。我确实尝试使用 promise,但也没有用。
let finalData = [];
Model.afterRemote('find', function(ctx, instance, next) {
if (ctx.result) {
if (Array.isArray(ctx.result)) {
ctx.result.forEach(function(result) {
Model.findById(result.id, {
include: {
relation: 'users',
scope: {
fields: ['email']
}
}
},
function(err, response) {
finalData.push(response);
console.log(finalData); // has the user information
});
});
}
ctx.result = finalData;
console.log(ctx.result); // --> empty result (need the finalData result)
}
next();
});
您需要了解异步函数和命令顺序。
虽然我认为您可以对 API 进行不同的查询来实现您的需要。
但无论如何,我会这样调用你的函数:
Model.afterRemote('find', function(ctx, instance, next) {
let finalData = [];
if (ctx.result) {
if (Array.isArray(ctx.result)) {
// map your results to array of id's
const ids = ctx.result.map(res => res.id);
// get result with different search query
const response = await Arscenes.find({where: {id: {inq: ids}}}, {
include: [{
relation: 'users',
scope: {
fields: ['email']
}
}]
});
// put the reuslts in ctx.result
ctx.result = response;
// call next() to end the call
next();
}
} else {
// call next() to end the call only in else case, in your example you're calling that before anything else so the request is over
next();
}
});
为什么不使用过滤器调用远程方法?您的方式带来了非常低效的 N+1 查询。无需在您的用例中实施 afterRemote
。在您的 API 通话中使用以下过滤器:
{
"include": {
"relation": "users",
"scope": {
"fields": ["email"]
}
}
}
我能够从 findById 函数内部推送结果并且日志打印正确,但在 forEach 循环之外它只是空的。我确实尝试使用 promise,但也没有用。
let finalData = [];
Model.afterRemote('find', function(ctx, instance, next) {
if (ctx.result) {
if (Array.isArray(ctx.result)) {
ctx.result.forEach(function(result) {
Model.findById(result.id, {
include: {
relation: 'users',
scope: {
fields: ['email']
}
}
},
function(err, response) {
finalData.push(response);
console.log(finalData); // has the user information
});
});
}
ctx.result = finalData;
console.log(ctx.result); // --> empty result (need the finalData result)
}
next();
});
您需要了解异步函数和命令顺序。
虽然我认为您可以对 API 进行不同的查询来实现您的需要。
但无论如何,我会这样调用你的函数:
Model.afterRemote('find', function(ctx, instance, next) {
let finalData = [];
if (ctx.result) {
if (Array.isArray(ctx.result)) {
// map your results to array of id's
const ids = ctx.result.map(res => res.id);
// get result with different search query
const response = await Arscenes.find({where: {id: {inq: ids}}}, {
include: [{
relation: 'users',
scope: {
fields: ['email']
}
}]
});
// put the reuslts in ctx.result
ctx.result = response;
// call next() to end the call
next();
}
} else {
// call next() to end the call only in else case, in your example you're calling that before anything else so the request is over
next();
}
});
为什么不使用过滤器调用远程方法?您的方式带来了非常低效的 N+1 查询。无需在您的用例中实施 afterRemote
。在您的 API 通话中使用以下过滤器:
{
"include": {
"relation": "users",
"scope": {
"fields": ["email"]
}
}
}