Suat Karabacak
Suat Karabacak

Reputation: 651

Angular async function call from template

I try to build an image-cache service for my Ionic application.

<ion-col [routerLink]="['/category-detail',cat.objectId,i]" class="category-item"
      *ngFor="let cat of categories;index as i" size="3">
      <ion-img class="cat-image" [src]="getImage(cat.image.url) | async">
      </ion-img>
      <p class="cat-name">
        {{cat.name}}
      </p>
    </ion-col>

I am calling the function from src tag in ion-image

async getImage(fileUrl: any) {
    return await this.cacheService.checkFile(fileUrl);
  }

This functions checking a file if its there it returns URL of file else it returns URL in parameter

public async checkFile(fileUrl) {
    let stringURL = String(fileUrl);
    let fileName = stringURL.split('//')[1].replace(/\//g, '-');
    return this.file.checkFile(this.file.tempDirectory, fileName)
      .then(
        async result => {
          if (result) {
            return this.file.tempDirectory + fileName;
          } else {
            return fileUrl;
          }
        }
      )
      .catch(
        async err => {
          //FileError.NOT_FOUND_ERR
          if (err.code == 1) {
            let fileTransfer: FileTransferObject = this.transfer.create();
            return fileTransfer.download(fileUrl, this.file.tempDirectory + fileName, true)
              .then(
                result => {
                  console.log(result);
                  return result;
                }
              )
              .catch(
                error => {
                  throw error;
                }
              )

          } else {
            throw err;
          }

        }
      )
  }

I searched various of questions and examples but none of them worked for me.

My goal is try to return a dynamic URL with a promise chain.

I am so confused with async,promise and observable keywords in Angular.

My project config :

Ionic:

   Ionic CLI                     : 6.9.1 (/Users/suatkarabacak/npm/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.1.1
   @angular-devkit/build-angular : 0.803.26
   @angular-devkit/schematics    : 8.3.26
   @angular/cli                  : 8.3.26
   @ionic/angular-toolkit        : 2.2.0

Cordova:

   Cordova CLI       : 9.0.0 ([email protected])
   Cordova Platforms : android 8.1.0, ios 5.1.1
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.2.1, (and 7 other plugins)

Utility:

   cordova-res : 0.14.0
   native-run  : 1.0.0

System:

   ios-deploy : 1.9.4
   ios-sim    : 8.0.2
   NodeJS     : v10.16.3 (/usr/local/bin/node)
   npm        : 6.9.0
   OS         : macOS Catalina
   Xcode      : Xcode 11.3 Build version 11C29

Upvotes: 8

Views: 17968

Answers (2)

Xinan
Xinan

Reputation: 3162

I would use a custom pipe in this case to implement your requirement.

so basically you have something like the following in your template:

<ion-col ... *ngFor="let cat of categories ..." ...>
   <ion-img ... [src]="cat | catImageUrl | async"></ion-img>
</ion-col>

Then you'll implement a custom Angular pipe getting cat image URL from a cat object asynchronously:

@Pipe({name: 'catImageUrl'})
export class CatImageUrlPipe implements PipeTransform {
  constructor(/* inject your cache service */) {}

  transform(cat: Category): Promise<string> {
    return this.cacheService.checkFile(cat.image.url);
  }
}

And that's all you need. Basically you compose 2 pipes together to make a Category -> Promise<string> -> string transformation to get the image url.

Upvotes: 7

Poul Kruijt
Poul Kruijt

Reputation: 71891

Ignoring your checkFile method, but you can use the async pipe:

image : Promise<any>;

ngOnInit(): void {
  if (this.cat) {
    this.image = this.cacheService.checkFile(this.cat.image.url);
  }
}
<ion-img class="cat-image" [src]="image | async"></ion-img>

basically, you only need to use async/await if you really want to wait for a Promise. When you are actually returning the promise, there is no use of it. Just clutters your code

Upvotes: 1

Related Questions