Search code examples
angularamazon-s3aws-amplify

How do you display the list of keys returned by AWS Amplify Storage object?


When I call this.amplifyService.storage().list('') I am able to see when I console.log a list of keys for the objects in s3. However, when I try to assign that list to a property and use that in a ngFor in my template, I get the error: "Cannot set property 'files' of undefined".

I am new to both Angular and AWS, so I am sure I have not tried everything, and am missing something fundamental to one or both.

Here is my component called filegetter: filegetter.component.ts

import { Component, OnInit } from '@angular/core';
import { AmplifyService } from 'aws-amplify-angular';

@Component({
  selector: 'app-filegetter',
  templateUrl: './filegetter.component.html',
  styleUrls: ['./filegetter.component.scss']
})
export class FilegetterComponent implements OnInit {
  files = []
  constructor(private amplifyService: AmplifyService) { 
    this.amplifyService.storage().list('')
    .then(function (result) {
      console.log(result);
      this.files = result.json;
    })
    .catch(err => console.log(err))
  }

  ngOnInit() {

  }

}

Here is the template filegetter.component.html:


<h3>Files</h3>
<ul *ngIf="files">
    <li *ngFor="let file of files">{{file}}</li>
</ul>

Here is the errors in the console:

0: 
{key: "myphoto.png", eTag: key: "myphoto.png"lastModified: Wed Aug 07 2019 09:47:56 GMT-0700 (Pacific Daylight Time) {}size: 564355__proto__: 
Object1: {key: "teamsweet.jpg", eTag: ""xxxx"", lastModified: Wed Aug 07 2019 09:32:31 GMT-0700 (Pacific Daylight Time), size: 219655}eTag: ""xxxx""key: "teamsweet.jpg"lastModified: Wed Aug 07 2019 09:32:31 GMT-0700 (Pacific Daylight Time) {}size: 219655__proto__: 
Object2: {key: "test.txt", eTag: ""xxxx"", lastModified: Wed Aug 07 2019 09:37:54 GMT-0700 (Pacific Daylight Time), size: 8}eTag: ""xxxx""key: "test.txt"lastModified: Wed Aug 07 2019 09:37:54 GMT-0700 (Pacific Daylight Time) {}size: 8__proto__: Object3: {key: "undefined", eTag: ""xxxx"", lastModified: Wed Aug 07 2019 09:30:33 GMT-0700 (Pacific Daylight Time), size: 219655}eTag: ""xxxx""key: "undefined"lastModified: Wed Aug 07 2019 09:30:33 GMT-0700 (Pacific Daylight Time) {}size: 219655__proto__: 
Objectlength: 4__proto__: Array(0)
filegetter.component.ts:17 TypeError: Cannot set property 'files' of undefined
    at filegetter.component.ts:15
    at ZoneDelegate.invoke (zone-evergreen.js:359)
    at Object.onInvoke (core.js:32838)
    at ZoneDelegate.invoke (zone-evergreen.js:358)
    at Zone.run (zone-evergreen.js:124)
    at zone-evergreen.js:855
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:32819)
    at ZoneDelegate.invokeTask (zone-evergreen.js:390)
    at Zone.runTask (zone-evergreen.js:168)```

Solution

  • The issue is because of function scope, the solution to this is fat arrow

    Change this :

    .then(function (result) { // <---- Because of function()
        console.log(result);
        this.files = result.json; //<--- this.files is not accesible
    })
    

    To :

    .then((result) => { // <----- CHANGE IS HERE
        console.log(result);
        this.files = result.json;
    })
    

    For more detail : DO READ