0

response screenshot image I receive an array of values from JavaScript promise. When I console.log, I can print it's value. But cannot print its array.length. please see te comments in getImageUrl() method

    public saveImages() {        
        for (let img of this.multipleImages) {
            if (img.file) {
                this.promise = this.FileUploadService.
                    addFile(img.file, img.randomName);
                this.promise.then(result => { 
                    this.setImageUrl(result);
                });
            }                     
        }
    }
    setImageUrl(result) {
        this.imageUrl.push(result);
    }
    getImageUrl() {
        console.log(this.imageUrl.length, // length is always 0
            this.imageUrl[0], //undefined
            this.imageUrl); // has  value (result from promise)
    }
    ngOninit() {
        this.saveImages();//saves the image and calls the setImageUrl method.
        this.getImageUrl();
    }

when this.getImageUrl() is called, you can see what is print and what is not in the console.log of getImageUrl() method.

kaws
  • 29
  • 6
  • When you console.log `this.imageUrl` what exactly do you see? – StudioTime Jul 12 '17 at 09:47
  • list of image urls in array. – kaws Jul 12 '17 at 09:49
  • i get the response . this isnt dupe. – kaws Jul 12 '17 at 09:50
  • if someone cant answer don't downvote pls. – kaws Jul 12 '17 at 09:51
  • could you please update the question with your `response.` . Also, what would happen if you call `this.getImageUrl()` after your `for` loop. – Bhavik Patel Jul 12 '17 at 09:51
  • 2
    ``this.getImageUrl()`` is being executed before ``this.setImageUrl()`` .So call your ``this.getImageUrl()`` inside your promise block . – CruelEngine Jul 12 '17 at 09:54
  • and this is because of the `asynchronous` nature. That is why it was a possible dup. – Bhavik Patel Jul 12 '17 at 09:57
  • Is this.imageUrl an object or array or string? if this.imageUrl is string or array then you will be able to print length. You can not find length property in an object. – Raj Bahadur Singh Jul 12 '17 at 09:59
  • It is an array of string. In the console I can see its length. – kaws Jul 12 '17 at 10:07
  • Your async operations (promises in `saveImages`) will be executed after your sync operations (`getImageUrl`). CruelEngine is correct. This is a duplicate – eko Jul 12 '17 at 10:18
  • The screenshot of response is attached in the post. – kaws Jul 12 '17 at 10:19
  • The reason why your array is printed is that console.log will print the objects latest value to the console (object mutation). You shouldn't debug your code with console.logs, use breakpoints. Then you will see that the value is actually undefined. – eko Jul 12 '17 at 10:24

1 Answers1

0

Try remove the for loop & skip overwriting your this.promise instance every iteration in that loop.

So, something like this:

const saveImages = () => Promise.all(this.multipleImages
  .map(img => img && img.file ? this
    .FileUploadService.addFile(img.file, img.randomName)
    .then(this.setImageUrl.bind(this)) : null
  ))

 // Then use with:
 saveImages()
   .then(() => this.getImageUrl())

Btw, here's where I'm working on these Promise ideas: https://github.com/justsml/escape-from-callback-mountain/

Dan Levy
  • 1,214
  • 11
  • 14
  • thanks and pls upvote the question. – kaws Jul 13 '17 at 11:44
  • Done. If it worked pls upvote my answer :) – Dan Levy Jul 13 '17 at 19:49
  • Done. I already found my answer. I still appreciate you for figuring out the problem. – kaws Jul 14 '17 at 06:51
  • in your answer you used map to call the function addFile, how do i pass the argument img.file only if it is not null? – kaws Jul 16 '17 at 08:50
  • Hey @kaws I updated my code snippet to return null if `img.file` is null. I added a little boolean expression after the `.map` and before `this.FileService...`. Don't forget the trailing `: null` after the `.then` bit. – Dan Levy Jul 16 '17 at 23:28