skip to Main Content

I am new in Javascript so pardon me if my question seems lame to you. What I am doing here is that posting 6 images on Facebook page through Graph-API one after another. So I am calling the POST function with an URL parameter, then when I got the photoID from that call, I made another call to read the photo with that photoID and get the original image from the image object of that response with the help of actual width and height of that image.

This is the call for posting image on Facebook page:

function postImageOnFacebookPageAndGetPhotoID(url) {
  return new Promise(function(resolve, reject) {
    FB.api(
      '/'+pageID+'/photos',
      'POST',
      {"url":url, "access_token":document.getElementById("pageAccessToken").value},
      function(response) {
        if (!response || response.error) {
          reject(response.error);
        } else {
          resolve(response.id);
        }
      }
    );
  });
}   

And this is how I am getting the PhotoID:

postImageOnFacebookPageAndGetPhotoID(wallpaper1125_2436Url).then(
  function(result) {
    if (result) {
      //Get the original image by photoID with the help of width and height
      //Here result is the photoID
      var photoID_1125_2436 = result;
      console.log(photoID_1125_2436);
    }
  }).catch(
    function(error) {
      alert(error);
    }
  )

The image size of my wallpaper is 1125x2436, so I am making another call to read the image from Facebook with the actual size of my image and photoID like this:

Function for getting image with the actual width and height from facebook:

function getOriginalUploadedImageURL(photoID, imageWidth, imageHeight) {
  return new Promise(function(resolve, reject) {
    FB.api(
      '/'+photoID,
      'GET',
      {"fields":"images"},
      function(response) {
        if (!response || response.error) {
          reject(response.error);
        } else {
          var imageArray = response.images;
          imageArray.forEach((item) => {
            if (item.width == imageWidth && item.height == imageHeight) {
              resolve(item.source);
            }
          });
        }
      }
    );
  });
}

And I am calling the this function under my 1st promise resolve like this:

postImageOnFacebookPageAndGetPhotoID(wallpaper1125_2436Url).then(
  function(result) {
    if (result) {
      //Get the original image by photoID with the help of width and height
      //Here result is the photoID
      var photoID_1125_2436 = result;
      getOriginalUploadedImageURL(photoID_1125_2436, "1125", "2436").then(
        function(result) {
          if (result) {
            //result is the original photo url of the uploaded image
            console.log(result);
          }
        }).
        catch(
          function(error) {
            alert(error);
          }
        )
    }
  }).
  catch(
    function(error) {
      alert(error);
    }
  )

This is working perfectly for one image. But when I try this approach with all of my 6 images it stops giving back any resolve or reject after 2 iteration, and the whole things looks wired:

postImageOnFacebookPageAndGetPhotoID(wallpaper1125_2436Url).then(
      function(result) {
        if (result) {
          //Get the original image by photoID with the help of width and height
          //Here result is the photoID
          var photoID_1125_2436 = result;
          console.log("Get photoID_1125_2436"+result);
          getOriginalUploadedImageURL(photoID_1125_2436, "1125", "2436").then(
            function(result) {
              if (result) {
                //result is the original photo url of the uploaded image
                wallpaper1125_2436Url = result;
                console.log("Get wallpaper1125_2436Url"+result);
                //Post the wallpaper1242_2208Url in facebook page
                postImageOnFacebookPageAndGetPhotoID(wallpaper1242_2208Url).then(
                  function(result) {
                    if (result) {
                      //Get the original image by photoID with the help of width and height
                      //Here result is the photoID
                      var photoID_1242_2208 = result;
                      console.log("Get photoID_1242_2208"+result);
                      getOriginalUploadedImageURL(photoID_1242_2208, "1242", "2208").then(
                        function(result) {
                          if (result) {
                            //result is the original photo url of the uploaded image
                            wallpaper1242_2208Url = result;
                            console.log("Get wallpaper1242_2208Url"+result);
                            //Post the wallpaper1242_2688Url in facebook page
                            postImageOnFacebookPageAndGetPhotoID(wallpaper1242_2688Url).then(
                              function(result) {
                                if (result) {
                                  //Get the original image by photoID with the help of width and height
                                  //Here result is the photoID
                                  var photoID_1242_2688 = result;
                                  console.log("Get photoID_1242_2688"+result);
                                  getOriginalUploadedImageURL(photoID_1242_2688, "1242", "2688").then(
                                    function(result) {
                                      if (result) {
                                        //result is the original photo url of the uploaded image
                                        wallpaper1242_2688Url = result;
                                        console.log("Get wallpaper1242_2688Url"+result);
                                        //Post the wallpaper828_1792Url in facebook page
                                        postImageOnFacebookPageAndGetPhotoID(wallpaper828_1792Url).then(
                                          function(result) {
                                            if (result) {
                                              //Get the original image by photoID with the help of width and height
                                              //Here result is the photoID
                                              var photoID_828_1792 = result;
                                              console.log("Get photoID_828_1792"+result);
                                              getOriginalUploadedImageURL(photoID_828_1792, "828", "1792").then(
                                                function(result) {
                                                  if (result) {
                                                    //result is the original photo url of the uploaded image
                                                    wallpaper828_1792Url = result;
                                                    console.log("Get wallpaper828_1792Url"+result);
                                                    //Post the wallpaper750_1334Url in facebook page
                                                    postImageOnFacebookPageAndGetPhotoID(wallpaper750_1334Url).then(
                                                      function(result) {
                                                        if (result) {
                                                          //Get the original image by photoID with the help of width and height
                                                          //Here result is the photoID
                                                          var photoID_750_1334 = result;
                                                          console.log("Get photoID_750_1334"+result);
                                                          getOriginalUploadedImageURL(photoID_750_1334, "750", "1334").then(
                                                            function(result) {
                                                              if (result) {
                                                                //result is the original photo url of the uploaded image
                                                                wallpaper750_1334Url = result;
                                                                console.log("Get wallpaper750_1334Url"+result);
                                                                //Post the wallpaper640_1136Url in facebook page
                                                                postImageOnFacebookPageAndGetPhotoID(wallpaper640_1136Url).then(
                                                                  function(result) {
                                                                    if (result) {
                                                                      //Get the original image by photoID with the help of width and height
                                                                      //Here result is the photoID
                                                                      var photoID_640_1136 = result;
                                                                      console.log("Get photoID_640_1136"+result);
                                                                      getOriginalUploadedImageURL(photoID_640_1136, "640", "1136").then(
                                                                        function(result) {
                                                                          if (result) {
                                                                            //result is the original photo url of the uploaded image
                                                                            wallpaper640_1136Url = result;
                                                                            console.log("Get wallpaper640_1136Url"+result);
                                                                            //Here I need to get all of my 6 image url for desired image with and height
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper1125_2436Url);
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper1242_2208Url);
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper1242_2688Url);
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper828_1792Url);
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper750_1334Url);
                                                                            console.log("Get wallpaper640_1136Url"+wallpaper640_1136Url);
                                                                          }
                                                                        }).catch(
                                                                          function(error) {
                                                                            document.getElementById("loaderId").style.visibility = 'hidden';
                                                                            alert(error);
                                                                          }
                                                                        )
                                                                    }
                                                                  }).catch(
                                                                    function(error) {
                                                                      document.getElementById("loaderId").style.visibility = 'hidden';
                                                                      alert(error);
                                                                    }
                                                                  )
                                                              }
                                                            }).catch(
                                                              function(error) {
                                                                document.getElementById("loaderId").style.visibility = 'hidden';
                                                                alert(error);
                                                              }
                                                            )
                                                        }
                                                      }).catch(
                                                        function(error) {
                                                          document.getElementById("loaderId").style.visibility = 'hidden';
                                                          alert(error);
                                                        }
                                                      )
                                                  }
                                                }).catch(
                                                  function(error) {
                                                    document.getElementById("loaderId").style.visibility = 'hidden';
                                                    alert(error);
                                                  }
                                                )
                                            }
                                          }).catch(
                                            function(error) {
                                              document.getElementById("loaderId").style.visibility = 'hidden';
                                              alert(error);
                                            }
                                          )
                                      }
                                    }).catch(
                                      function(error) {
                                        document.getElementById("loaderId").style.visibility = 'hidden';
                                        alert(error);
                                      }
                                    )
                                }
                              }).catch(
                                function(error) {
                                  document.getElementById("loaderId").style.visibility = 'hidden';
                                  alert(error);
                                }
                              )
                          }
                        }).catch(
                          function(error) {
                            document.getElementById("loaderId").style.visibility = 'hidden';
                            alert(error);
                          }
                        )
                    }
                  }).catch(
                    function(error) {
                      document.getElementById("loaderId").style.visibility = 'hidden';
                      alert(error);
                    }
                  )
              }
            }).catch(
              function(error) {
                document.getElementById("loaderId").style.visibility = 'hidden';
                alert(error);
              }
            )
        }
      }).catch(
        function(error) {
          document.getElementById("loaderId").style.visibility = 'hidden';
          alert(error);
        }
      )

So how can I do it correctly? Sorry again for too much code.
A lot of thanks in advance.

3

Answers


  1. Two answers for you, but they both make use of the fact you can chain rather than nesting those handlers. Instead of:

    doThis()
    .then(function(thisResult) {
        doThat()
        .then(function(thatResult) {
            doTheOther()
            .then(function(theOtherResult) {
                // ...
            });
        })
        .catch(/*...*/);
    })
    .catch(/*...*/);
    

    do this:

    doThis()
    .then(function(thisResult) {
        return doThat();
    })
    .then(function(thatResult) {
        return doTheOther();
    })
    .then(function(theOtherResult) {
        // ...
    })
    .catch(/*...*/);
    

    The "two answers" comes in because:

    1. The first answer uses discrete variables as in your original code:

    // *** Declare them here
    let photoID_1125_2436, wallpaper1125_2436Url/*, ...*/;
    // *** Fill them in with the promise fulfillment handlers
    postImageOnFacebookPageAndGetPhotoID(wallpaper1125_2436Url)
    .then(function(result) {
        if (!result) {
            return result;
        }
        //Get the original image by photoID with the help of width and height
        //Here result is the photoID
        photoID_1125_2436 = result;
        console.log("Get photoID_1125_2436"+result);
        return getOriginalUploadedImageURL(photoID_1125_2436, "1125", "2436");
     })
    .then(function(result) {
        if (!result) {
            return result;
        }
        //result is the original photo url of the uploaded image
        wallpaper1125_2436Url = result;
        console.log("Get wallpaper1125_2436Url"+result);
        //Post the wallpaper1242_2208Url in facebook page
        return postImageOnFacebookPageAndGetPhotoID(wallpaper1242_2208Url);
    })
    .then(function(result) {
        // ...and so on...
    })
    .then(function(result) {
        if (!result) {
            return result;
        }
        wallpaper640_1136Url = result;
        console.log("Get wallpaper640_1136Url"+result);
        // *** Use them all here
        console.log("Get wallpaper640_1136Url"+wallpaper1125_2436Url);
        console.log("Get wallpaper640_1136Url"+wallpaper1242_2208Url);
        console.log("Get wallpaper640_1136Url"+wallpaper1242_2688Url);
        console.log("Get wallpaper640_1136Url"+wallpaper828_1792Url);
        console.log("Get wallpaper640_1136Url"+wallpaper750_1334Url);
        console.log("Get wallpaper640_1136Url"+wallpaper640_1136Url);
    })
    .catch(function(error) {
        document.getElementById("loaderId").style.visibility = 'hidden';
        alert(error);
    });
    

    2. The second one uses a loop instead of repeated identical functions

    const wallpaperUrls = [
        {width: "1125", height: "2436", url: /*...*/,}
        {width: "1242", height: "2208", url: /*...*/,}
        {width: "1242", height: "2688", url: /*...*/,}
        {width: "828",  height: "1792", url: /*...*/,}
        {width: "750",  height: "1334", url: /*...*/,}
        {width: "640",  height: "1136", url: /*...*/,}
    ];
    const results = {};
    const promise = Promise.resolve();
    for (const {width, height, url} of wallpaperUrls) {
        promise = promise.then(() => {
            return postImageOnFacebookPageAndGetPhotoID(url)
            .then(result => {
                return result && getOriginalUploadedImageURL(result, width, height);
                // *** ^^^^^^^^^^−−−− It seems odd to me that the promise could be fullfilled but
                //                    not provide a valid result; hopefully you don't need this
            })
            .then(imageUrl => {
                if (imageUrl) { // *** It seems odd to me that the promise could be fullfilled but
                                //    not provide a valid result; hopefully you don't need this
                    results[`${width}_${height}`] = imageUrl;
                }
            })
        });
    }
    promise
    .then(() => {
        // ...use `results` here, it's keyed by width_height
    })
    .catch(error => {
        document.getElementById("loaderId").style.visibility = 'hidden';
        alert(error);
    }) ;
    

    Note that that does everything in series, one after another, like your original example. But you could do them in parallel instead:

    const wallpaperUrls = [
        {width: "1125", height: "2436", url: /*...*/,}
        {width: "1242", height: "2208", url: /*...*/,}
        {width: "1242", height: "2688", url: /*...*/,}
        {width: "828",  height: "1792", url: /*...*/,}
        {width: "750",  height: "1334", url: /*...*/,}
        {width: "640",  height: "1136", url: /*...*/,}
    ];
    const results = {};
    Promise.all(wallpaperUrls.map(({width, height, url}) => {
        return postImageOnFacebookPageAndGetPhotoID(url)
        .then(result => {
            return result && getOriginalUploadedImageURL(result, width, height);
            // *** ^^^^^^^^^^−−−− It seems odd to me that the promise could be fullfilled but
            //                    not provide a valid result; hopefully you don't need this
        })
        .then(imageUrl => {
            if (imageUrl) { // *** It seems odd to me that the promise could be fullfilled but
                            //    not provide a valid result; hopefully you don't need this
                results[`${width}_${height}`] = imageUrl;
            }
        })
    });
    .then(() => {
        // ...use `results` here, it's keyed by width_height
    })
    .catch(error => {
        document.getElementById("loaderId").style.visibility = 'hidden';
        alert(error);
    });
    

    I’ve stuck to .then and .catch, etc., above because your code wasn’t using async/await. But the code would be easier to write and easier to read if you were using async/await, which you can do in many environments natively (and in just about any environment if you transpile).


    Please note: There may be minor errors in the above. I didn’t run or even syntax-check the code. You’re bound to need to make some adjustments here and there. 🙂

    Login or Signup to reply.
  2. I think you could use Promise.all(array of promises) [Promise.all](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all.

    postImageOnFacebookPageAndGetPhotoID(wallpaper1125_2436Url).then(
      function(result) {
        if (result) {
          //Get the original image by photoID with the help of width and height
          //Here result is the photoID
          var photoID_1125_2436 = result;
          return getOriginalUploadedImageURL(photoID_1125_2436, "1125", "2436").then(
            function(result) {
              if (result) {
                //result is the original photo url of the uploaded image
                console.log(result);
                return result
              }
            }).
            catch(
              function(error) {
                alert(error);
              }
            )
        }
      }).
      catch(
        function(error) {
          alert(error);
        }
      )
    
    // Then use Promise.all for all the 6 images
    
    Promise.all([
      postImageOnFacebookPageAndGetPhotoID(url 1), 
      postImageOnFacebookPageAndGetPhotoID(url 2) 
      ... 
      upto 6 images
    ])
      .then((results) => console.log(results))
    

    Here the results will be an array containing results from each individual call in the same order as passed to Promise.all()

    Then you can attach a single catch at the end of Promise.all.

    Login or Signup to reply.
  3. just abstract your function

    function yourfunction(arg){
      return new Promise((resolve,reject)=>{
        if(Math.random() > 0.9){
          console.log(arg,'failed');
          reject();
        }else{
          console.log(arg,'ok');
          resolve();
        }
      });
    }
    
    // run all
    function allok(){
      let arr = [];
      for(let i = 0;i<6;i++){
        arr.push(yourfunction(i));
      }
      return Promise.all(arr).then(()=>{
        console.log('all ok');
        return true;
      }).catch(()=>{
        console.log('some func failed');
        return Promise.resolve(false);
      });
    }
    
    
    async function oneByone(){
      try{
        for(let i = 0;i<6;i++){
          await yourfunction(i);
        }
      }catch(e){
        console.log('some func failed');
        return false;
      }
      console.log('all ok');
      return true;
    }
    
    

    if you want call all the functions and check if all of them is ok call allok();

    or you want call the functions one by one till some failed, call oneByone();

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search