Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a promise work inside a JavaScript switch/case

I having a problem (well two if I'm honest) getting a promise or a callback to work inside a switch-case. Here is the basic code.

switch (page) {

  case 'contact':

   alert('contact in switch');

   var promise = $.get(page +'.json');
   promise.then(function(data){
     console.log("Items back! ", data);                     
   });

  break;
  .......

  console.log("Response data: ", data); // This is undefined

I understand that due to the nature of async functions, the switch is falling through to the break before the data comes back, making data log as undefined. So I thought putting the break inside the callback would work but it doesn't. When I do that the app stops working entirely.

So I guess my first question is how do I make the switch-case "wait" until the data comes back before going to break.

The second problem I have is that I ultimately want to be able to reuse my switch by wrapping it in a function where the page argument is the title of the page the user is navigating to and the callback will pass back the data returned from the getPageData function. When I try this it results in an undefined error for the callback of the pageContentLoaderfunction.

For the record, the getPageDatain the code below is a separate function which performs a generic XMLHttpRequest. It's working fine because the data gets logged correctly in the callback.

pageContentLoader(page, function(data) {
                    console.log("Back with data ", data);   
});

function pageContentLoader(page, callback){
    var data;

            switch (page) {
                case 'contact':
                    console.log('contact in switch');
                    getPageData(page,function(data){
                      console.log("Contacts back! ", data);     
                    });             
                    break;    
                case 'blog':
                    console.log('blog in switch');
                    getPageData(page,function(data){
                        console.log("Posts back! ", data);      
                    });                 
                    break;    
                default:
                    alert('hey that page doesn't exist!');    
            } 
            callback(data); // results in callback undefined!!
}   

I am sure it is possible to make this work but I've tried everything I can find without any luck so far. If anyone has any pointers or wants to tell me what I am doing wrong within my code I'd be grateful!

like image 921
mikeym Avatar asked Oct 21 '16 21:10

mikeym


People also ask

Can we use expression in switch case in JavaScript?

The switch statement evaluates an expression. The value of the expression is then compared with the values of each case in the structure. If there is a match, the associated block of code is executed. The switch statement is often used together with a break or a default keyword (or both).

Can we use if condition inside switch case?

Yes, and just like that.

What is the problem with promises in JavaScript?

Promises co-mingle rejected promises and unintended runtime exceptions. Apart from how the API is structured - promises have another major flaw: they treat unintentional native runtime exceptions and intentional rejected promises - which are two drastically different intentions - in the same "path".

Can we use promise Inside promise?

Here we need to first declare a Promise by using the Promise syntax, and we will be using the then() method for its execution and then inside that then() method we will create another promise by using the same Promise syntax as illustrated above, and then we will call our result of first inside that new Promise.


2 Answers

Just ran into to this problem earlier, solved it as follows:

async getResolvedPromises(myObject) {
    const promises = await Object.keys(myObject).map(async (k) => {
        switch (k) {
            case '1':
                const firstPromise = await asyncCallNumber1()
                return firstPromise
            case '2':
                const secondPromise = await asyncCallNumber2()
                return secondPromise
            case '3':
                const thirdPromise = await asyncCallNumber3()
                return thirdPromise
            default:
                return
        }
    })

    const data = await Promise.all(promises)
    return data
}
like image 158
rc_dz Avatar answered Nov 14 '22 21:11

rc_dz


Here's a recent example in Typescript that I've adapted:

private pageContentLoader = async (): Promise<any> => {
    try {
        switch(page) {
            case 'contact':
                return await getPageData(page).then((data) => {
                    console.log("Contacts back! ", data);
                    return data;
                })
            case 'blog':
                return await getPageData(page).then((data) => {
                    console.log("Posts back! ", data);
                    return data;
                })
            default:
                return 'Page does not exist';
        }   
    } catch (err) {
        throw err;
    }
}


private getPageContent = async () => {
    try {
        const contactPageData = await pageContentLoader('contact');
        const blogPageData = await pageContentLoader('blog');
    } catch (err) {
        throw err;
    }
};
like image 44
Jawa the Hutt Avatar answered Nov 14 '22 21:11

Jawa the Hutt