3

What I'm working with

  • angular2
  • firebase

What I have

  • A returned object
  • Each item in the object has a URL property

What I would like to do

  • Loop through each of the items in the object and get the URL property
  • Pass that into a firebase storage variable
  • Push the URL property into an array to make available for my HTML

note: I have this working by hard coding a url, I just need some assistance looping through the object to get the other urls in the object.

Component.ts

'this.imagesToDisplay' will return an object of object (image below)

this.activatedRoute.data
  .subscribe((
    data: { issueData: any, issueImageData: any }) => {
    this.issueToDisplay = data.issueData;
    this.imagesToDisplay = data.issueImageData; 

    this.testing(this.imageToDisplayArray); 

  });
enter image description here

Comnponent TS - Testing method

So this is hardcoded and pushes the hardcoded url into the array and displays correctly through databinding with the HTML. Cool. However, I would like to loop through the 'imagesToDisplay' object and get both returned urls.

  testing(imageToDisplayArray) {
    
    // this works with one url
    var storage = firebase.storage().ref().child("image/-Kosd82P-bmh4SFetuf3/-Kosd8HhGmFiUhYMrlvw/30DD9F39-4684-4AA0-9DBF-3B0F0C3450A4.jpg");
    storage.getDownloadURL().then(function(url) {
    imageToDisplayArray.push(url);
        console.log(imageToDisplayArray);
    });

  }

Any help here would be massively appreciated.

Note: I think this question here is what I'm trying to do, I'm just not sure how to integrate that into my current code. Any help would be awesome. Stack Overflow question on firebase storage looping

UPDATE

So, I'm incredibly close now. I just have one issue. The code below loops through the returned data and extract the URL properties. I use the url properties to connect to the firebase storage and return the download URLs. Both of these are logged to the console! Awesome. I now have the URLs i needed! The issue I'm having is, it will only let me push these values to a local array. In this instance 'var array'. I need to push to an array that's outside of the 'activatedRoute' 'method'. Anytime I do, it returns as undefined.

this.activatedRoute.data
      .subscribe((
        data: { issueData: any, issueImageData: any }) => {
        this.issueToDisplay = data.issueData;
        this.imagesToDisplay = data.issueImageData;

        var array = [];

        data.issueImageData.forEach(image => {

          // Reference to the image URL
          var image = image.url;

          // Firebase storage
          var storage = firebase.storage();

          // Path reference
          var imagePathReference = storage.ref().child(image);

          // Get Download URL
          imagePathReference.getDownloadURL().then(function (url) {
            console.log(url);
            array.push(url);
          })
        });


      });
MegaTron
  • 3,133
  • 6
  • 28
  • 45
  • Could you add an example of `this.imagesToDisplay`? A fully working example would be appreciated, thanks! – Sventies Jul 28 '17 at 08:04
  • And check this answer out for a general approach for iterating through an object: https://stackoverflow.com/questions/8312459/iterate-through-object-properties – Sventies Jul 28 '17 at 08:05
  • Hey @sventies. I'm not entirely sure how to present a working example of my angular solution outside of my environment unfortunately. There are quite a few connected files and dependencies at the moment. "this.imagesToDisplay" returns the data seen in the sreenshot. In this instance it's an object of object which contain the urls I need to loop through and push into an array. – MegaTron Jul 28 '17 at 08:26

3 Answers3

1

I would recommend you to use the features rxjs provides you:

this.activatedRoute.data.switchMap(data => {
    let parsedData = { 
        issueToDisplay: data.issueData,
        imagesToDisplay: data.issueImageData
    }
    let imageUrls$ = data.issueImageData.map(image => {
        var imagePathReference = storage.ref().child(image);
        return Observable.fromPromise(imagePathReference.getDownloadURL())
    });
    return Observable.forkJoin(imageUrls$).map((...urls) => {
        return Object.assign(parsedData, { urls });
    })
}).subscribe(data => {
    /* 
    data looks like this:
    {
        issueToDisplay: any,
        imagesToDisplay: any,
        urls: string[]
    }
    */
});
cyr_x
  • 13,987
  • 2
  • 32
  • 46
0

If I'm correct, you're looking for a solution to map an array-like object of objects to an actual array of objects.

Here is a way to do just that:

var object = {
  '0': {
    "url": "url1",
    "name": "obj1",
    "data": 1234
   },
  '1': {
    "url": "url2",
    "name": "obj2",
    "data": 5678
   },
   'length': 2
}

var sliced = Array.prototype.slice.call( object, 0 );

console.log(sliced)

Couple remarks:

  • If you wonder how this works, check this post.

  • Alternative syntax that you could encounter looks like [].slice.call()

  • If you want to perform array-like operations, you can probably do that right away with Array.prototype.<METHOD>.call(object, <CALLBACK>

  • For example:

Array.prototype.map.call(object, function(el) { // return your enhanced element })

Sventies
  • 2,314
  • 1
  • 28
  • 44
  • In short, I simply want the two urls (in this instance. It could 40) from that object and have them in an array that I can loop through. – MegaTron Jul 28 '17 at 09:00
  • It then means that once I have that array, I could probably do something like: var storage = firebase.storage().ref().child(). In the child it'll be each url from the array. That's the aim at least. – MegaTron Jul 28 '17 at 09:01
0

So, this works. Not entirely sure how clean it is. But it works.

 this.activatedRoute.data
      .subscribe((
        data: { issueData: any, issueImageData: any }) => {
        this.issueToDisplay = data.issueData;
        this.imagesToDisplay = data.issueImageData;

        var localImageArray = [];

        data.issueImageData.forEach(image => {

          // Reference to the image URL
          var image = image.url;

          // Firebase storage
          var storage = firebase.storage();

          // Path reference
          var imagePathReference = storage.ref().child(image);

          // Get Download URL
          imagePathReference.getDownloadURL().then(function (url) {
            localImageArray.push(url);
          })

            this.getIssueImageArray(localImageArray);
        });


      });
  }

  // Get Image Array
  getIssueImageArray(array) {
    this.imageToDisplayArray = array;
  }
MegaTron
  • 3,133
  • 6
  • 28
  • 45