Return external data in ctx.send from custom controller

System Information
  • Strapi Version: 3.5.2
  • Operating System: mac
  • Database: sqlite
  • Node Version: 14
  • NPM Version: 7.7.6
  • Yarn Version: 1.22.10

What am I doing wrong, the custom controller retrieves data from an external source in json format but I cannot send it back in ctx.send. When I hit the endpoint it just returns Not Found.

The data is retrieved from the external source as it can be logged to the console but it can’t be returned to the GET request that triggers it.

module.exports = {

    async index(ctx) {

        const tourId = ctx.params.id;
        
        TourCMS.showTour({
            channelId: channelId,
            tourId: tourId,
            callback: (response) => {
                console.log(response)
                ctx.send(response)
            }
        });
    }
};

My opinion - you don’t use await.
Now your code return empty resolved Promise

@Gayrat is right. Because you are not using await, it just executes everything and exists with an empty result. So your request to TourCMS finishes AFTER you receive Not Found (that’s why you see the console log).

Just add await before TourCMS.showTour().

Thank @Gayrat I did try that, I have an issue then though accessing the ctx within the promise scope, see the below revised code which gives ‘Not Found’ when I hit the endpoint.

I can console.log the results of the promise but cant send it back as a response.

module.exports = {

    async index(ctx) {

        const tourId = ctx.params.id;

         let tour = new Promise((resolve, reject)=> {
            TourCMS.showTour({
                channelId: channelId,
                tourId: tourId,
                callback: (response) => {
                    //console.log('response', response);
                    resolve(response)
                }
            });
         })

        tour.then(response => {
            console.log(response)
            ctx.send(response)
        })
                     
    }
};

I figured it out, using returns to resolve the promise and then returning that again, see below works:

module.exports = {

    async index(ctx) {

        const tourId = ctx.params.id;

         let tour = new Promise((resolve, reject)=> {
            TourCMS.showTour({
                channelId: channelId,
                tourId: tourId,
                callback: (response) => {
                    resolve(response)
                }
            });
         })

        return tour.then(response => {
            return response;
        }).catch(error => {
            console.log(error);
        })            
    }
};
1 Like