Nesquikk M
Nesquikk M

Reputation: 121

Angular observable subsribe to a property

This is a simple view of how i have set it up, the images array is actually inside a formgroup, which is in the end passed back to the C# backend

I wish to check if the images array contains more than 4 elements, otherwise set canAdd as false and now allow anymore images to be added to the images array, once an image gets removed from the array it should then be allowed again

export class SomeComponent implements OnInit {
  images = []
  canAdd: Observable<boolean>
  

constructor() { }
}

How do i set up the subscription ? between this array and the observable ?

I am adding to the image array like this

onFileChanged(files) {
  // Check here the observable if it canAdd

  if (files.length === 0)
    return;

  var mimeType = files[0].type;
  if (mimeType.match(/image\/*/) == null)
    return;

  var reader = new FileReader();
  reader.readAsDataURL(files[0]);
  reader.onload = (_event) => {
    this.images.push(reader.result);
  }
}

Upvotes: 0

Views: 89

Answers (1)

Matt
Matt

Reputation: 337

I don't know your specific usecase but depending on your logic, you can handle it in few different ways.

For example if you are handling upload and display in the same component and images is a public property on this component, you could do it like this:

<input type="file" (change)="onFileChanged($event)" multiple *ngIf="images?.length < 4">

If you are doing it somewhere else, then I would move logic to a separate service which would handle the upload process and tell the subscribers to hide/show input when the image array changes, e.g.:

@Injectable({
  providedIn: 'root'
})
export class UploadService {

  constructor() { }

    //if you want to hold images here
    private images: any[] = [];

  //use this to emit values to show/hide input
  private canAddSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
  readonly canAdd$: Observable<boolean> = this.canAddSubject.asObservable();

  //you can use another subject and observable if you want subscribe to images array changes
  //this way will allow you to handle it in a more reative way
  private imagesSubject: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
  readonly images$: Observable<any[]> = this.imagesSubject.asObservable();

  public onFileChanged(files): void {
    
      this.images.length > 4
        ? this.canAddSubject.next(false)
        : this.canAddSubject.next(true);

        //rest of the code omitted for brevity
    }
}

Then just inject service to your component and listen to canAdd$ changes with async pipe, e.g.:

<input type="file" (change)="onFileChanged($event)" multiple *ngIf="uploadService.canAdd$ | async">

Upvotes: 2

Related Questions