dagda1
dagda1

Reputation: 28810

refactor code from normal collections in angular 4 to use rxjs observables

I have code like this in components:

@Component({
  selector: 'file-upload',
})
export class FileUploadComponent  {
  files: Upload[];

  get canUpload() {
    return this.files.length > 0 && this.files.every((f) => f.state === FileUpLoadState.new && f.isValid);
  }

  get isUploading() {
    return this.files.length > 0 && this.files.some((f) => f.state === FileUpLoadState.uploading);
  }

  get activeFiles() {
    return this.files.filter((f) => f.state !== FileUpLoadState.success);
  }

I want to change the files member to a BehaviouSubject

  files: BehaviorSubject<FileToUpload[]> = new BehaviorSubject([]);

But I don't know hot to change the canUpload, isUploading etc. getters to use the observable, there is no pipe operator in rxjs 5.1.0 and upgrading is not an option for various reasons.

Do I need to subscribe in getter or is there a better way?

Upvotes: 0

Views: 55

Answers (1)

Evaldas Buinauskas
Evaldas Buinauskas

Reputation: 14077

You're correct that there's no pipe operator, but before rxjs V6 it used extension methods, so .map() and .filter() should still do the trick. I didn't have a chance to work with Angular V4, but this should work:

@Component({
  selector: 'file-upload',
})
export class FileUploadComponent  {
  files$ = new BehaviorSubject([]);

  get canUpload$() {
    return this.files$.map(files => files.length > 0 && this.files.every((f) => f.state === FileUpLoadState.new && f.isValid));
  }

  get isUploading$() {
    return this.files$.map(files => files.length > 0 && this.files.some((f) => f.state === FileUpLoadState.uploading));
  }

  get activeFiles$() {
    return this.files$.filter(files => files.filter((f) => f.state !== FileUpLoadState.success));
  }
}

Keep in mind that getters also become observables. If you don't want getters to be observables, you probably can subscribe to them within getter:

get activeFiles() {
  let files;

  this.files$
      .filter(files => files.filter((f) => f.state !== FileUpLoadState.success))
      .subscribe(s => files = s);

  return files;
}

But I'd personally stick with first approach and subscribe to observables at the most late stage as possible.

Upvotes: 1

Related Questions