System Information
4.0 :
Mac OS :
Database :
Node Version :
NPM Version :
Yarn Version :
const { createCoreController } = require("@strapi/strapi").factories;
module.exports = createCoreController(
"api::application.application",
({ strapi }) => ({
async getFormDetailsBasedOnApplicationAction(ctx) {
try {
/**
* Queries the RCMP collection type
* using the Entity Service APIs
* to retrieve information about the documents
*/
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{ messages: [{ id: "No authorization header was found" }] },
]);
}
const entries = await strapi.entityService.findMany(
"api::application.application",
ctx.query
);
const finalEntries = [];
Promise.all(
entries.map(async (entry) => {
let formData = {};
if (entry && entry.formType === "RCMP") {
formData = await strapi.entityService.findOne(
"api::rcmp-form.rcmp-form",
entry.orderId,
{
populate: { document: true },
}
);
finalEntries.push({ ...entry, formData });
} else if (entry && entry.formType === "FBI_APOSTILLE") {
formData = await strapi.entityService.findOne(
"api::fbi-apostille-form.fbi-apostille-form",
entry.orderId,
{
populate: { document: true },
}
);
finalEntries.push({ ...entry, formData });
}
})
)
.then((results) => {
ctx.body = {
data: finalEntries,
};
return ctx;
})
.catch((e) => {
ctx.body = e;
return ctx;
// Handle errors here
});
} catch (err) {
ctx.body = err;
return ctx;
}
},
})
);
Am i returning the data correctly? Or do I have to sanitize the output?
Hey @vinikatyal ,
It seems okay with the return method. You can also use ctx.send({}) instead of return/ctx.body .
Can you show me the console error?
Shekhar:
ctx.send({})
No errors just below message:
{
"data": null,
"error": {
"status": 404,
"name": "NotFoundError",
"message": "Not Found",
"details": {}
}
}
Have you given roles permission to the custom created API route?
Yes I have given, it works on my local gets all the data
But it doesn’t work on live server, right? Double check everything on live server too.
Shekhar:
ctx.send({})
yes double checked my routing is as below:
Hmm, that’s odd. Can you compare the whole Api url for both local and live server, see if anything’s wrong with the URL.
Also please adjust you route file code like below:
//.src/api/application/routes/application.js
'use strict';
const { createCoreRouter } = require('@strapi/strapi').factories;
const defaultRouter = createCoreRouter('api::application.application');
const customRouter = (innerRouter, extraRoutes = []) => {
let routes;
return {
get prefix() {
return innerRouter.prefix;
},
get routes() {
if (!routes) routes = innerRouter.routes.concat(extraRoutes);
return routes;
},
};
};
const myExtraRoutes = [
{
method: 'GET',
path:'/application-details',
handler:'api::application.application.getFormDetailsBasedOnApplicationAction'
}
];
module.exports = customRouter(defaultRouter, myExtraRoutes);
I am sure this will work properly at each places.
Shekhar:
const defaultRouter = createCoreRouter('api::application.application');
const customRouter = (innerRouter, extraRoutes = []) => {
let routes;
return {
get prefix() {
return innerRouter.prefix;
},
get routes() {
if (!routes) routes = innerRouter.routes.concat(extraRoutes);
return routes;
},
};
};
const myExtraRoutes = [
{
method: 'GET',
path:'/application-details',
handler:'api::application.application.getFormDetailsBasedOnApplicationAction'
}
];
module.exports = customRouter(defaultRouter, myExtraRoutes);
Tried this did not work
"use strict";
/**
* application controller
*/
const { createCoreController } = require("@strapi/strapi").factories;
module.exports = createCoreController(
"api::application.application",
({ strapi }) => ({
async getFormDetailsBasedOnApplicationAction(ctx) {
try {
/**
* Queries the RCMP collection type
* using the Entity Service APIs
* to retrieve information about the documents
*/
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{ messages: [{ id: "No authorization header was found" }] },
]);
}
const entries = await strapi.entityService.findMany(
"api::application.application",
ctx.query
);
const finalEntries = [];
Promise.all(
entries.map(async (entry) => {
let formData = {};
if (entry && entry.formType === "RCMP") {
formData = await strapi.entityService.findOne(
"api::rcmp-form.rcmp-form",
entry.orderId,
{
populate: { document: true },
}
);
finalEntries.push({ ...entry, formData });
} else if (entry && entry.formType === "FBI_APOSTILLE") {
formData = await strapi.entityService.findOne(
"api::fbi-apostille-form.fbi-apostille-form",
entry.orderId,
{
populate: { document: true },
}
);
finalEntries.push({ ...entry, formData });
}
})
)
.then(async (results) => {
const sanitizedEntries = await this.sanitizeOutput(
finalEntries,
ctx
);
console.log(sanitizedEntries)
return ctx.send(this.transformResponse(sanitizedEntries));
})
.catch((e) => {
ctx.body = e;
return ctx.send(this.transformResponse(e));
// Handle errors here
});
} catch (err) {
ctx.body = err;
return ctx.send(this.transformResponse(err));
}
},
})
);
**strong text**
Its weird because its consoling the output of sanitized entries on the server as well
Server outputs response but router says 404 not found
Shekhar
December 4, 2023, 9:40am
12
Okay. So there’s nothing wrong with the route call but something wrong with your Promise.all() code block.
I see you are using finalEntries.push() instead or returning value under the Promise.all(). Before the values are pushed in to the finalEntries the API just run off. Meaning, Api is executed successfully and is not awaiting for finalEntries values in response.
I think that might be the culprit
Can you test it by replacing the below code with your Promise code block:
const finalEntries = Promise.all(entries.map(async (entry) => {
let formData = {};
let responseData = {};
if (entry && entry.formType === "RCMP") {
formData = await strapi.entityService.findOne("api::rcmp-form.rcmp-form", entry.orderId, {
populate: { document: true },
});
} else if (entry && entry.formType === "FBI_APOSTILLE") {
formData = await strapi.entityService.findOne("api::fbi-apostille-form.fbi-apostille-form", entry.orderId, {
populate: { document: true },
});
}
responseData = { ...entry, formData };
}))
.catch((e) => {
ctx.body = e;
return ctx;
});
console.log(finalEntries) // Check this with your old code and then check it with the above code
I hope this may work as I use the same concept in my project.
Shekhar:
const finalEntries = Promise.all(entries.map(async (entry) => {
let formData = {};
let responseData = {};
if (entry && entry.formType === "RCMP") {
formData = await strapi.entityService.findOne("api::rcmp-form.rcmp-form", entry.orderId, {
populate: { document: true },
});
} else if (entry && entry.formType === "FBI_APOSTILLE") {
formData = await strapi.entityService.findOne("api::fbi-apostille-form.fbi-apostille-form", entry.orderId, {
populate: { document: true },
});
}
responseData = { ...entry, formData };
}))
.catch((e) => {
ctx.body = e;
return ctx;
});
Where exactly? should this be placed i dont see it returning the values
I understand what you are saying its actually not resolving the promise just going outside and trying to find a response but then it doesnt so it causes a 404 error
Shekhar
December 4, 2023, 11:19am
15
Yes correct. That’s what I was trying you to explain and that is why I shared you a different code.
Check my code, I have assigned return values from inside of the whole promise to finalEntries variable. Try debugging it using console.log().
Then send it to the api response via
ctx.body = finalEntries; OR ctx.send({ data: finalEntries })
Shekhar
December 4, 2023, 1:44pm
17
@vinikatyal I have to check it myself by creating a demo in my local and the following code worked for me.
The route url:
The controller function:
Output:
1 Like
Thanks so much really appreciate your replies
2 Likes
@Shekhar thank you for your help.
2 Likes