MurhafSousli / ngx-gallery

Angular Gallery, Carousel and Lightbox
https://ngx-gallery.netlify.app/
MIT License
608 stars 128 forks source link

Too much recursion inside gallerize #312

Closed yuniers closed 4 years ago

yuniers commented 4 years ago

What is the expected behavior?

When I use a gallery with gallerize on my browser console an Error are throw.

too much recursion Subscriber.js:191:31
    RxJS 8
        __tryOrUnsub
        next
        _next
        next
        _next
        next
        next
        next
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
        __tryOrUnsub
        next
        _next
        next
        _next
        next
        next
        next
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
        __tryOrUnsub
        next
        _next
        next
        _next
        next
        next
        next
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 8
    setState ngx-gallery-core.js:241
    load ngx-gallery-core.js:328
    galleryMode/this._itemChange$< ngx-gallery-gallerize.js:85
    RxJS 7

What is the current behavior?

The gallery are showing correctly.

What are the steps to reproduce?

Use a gallery with gallerize directive

<gallery [id]="id" [gallerize]="id" [items]="cameraImages"></gallery>

What is the use-case or motivation for changing an existing behavior?

Maybe this error damages component performance

Which versions are you using for the following packages?

Angular: 8.2.14 Angular CDK: 8.2.3 Angular CLI: 8.3.20 Typescript: 3.5.3 Gallery: 4.0.3

Is there anything else we should know?

Not, for now not.

MurhafSousli commented 4 years ago

Did you use OnPush change detection? please add a stackblitz reproduction

yuniers commented 4 years ago

Did you use OnPush change detection?

Before you comment I was not using OnPush change detection.

I add it to my custom gallery component. But any change.

I see in your examples using OnPush change detection.

please add a stackblitz reproduction

My gallery API are not public yet. But I can share my custom component.

yuniers commented 4 years ago

GalleryModule, LightboxModule and GallerizeModule are imported on parent module.

Component

import { ChangeDetectionStrategy, Component, Input, OnInit, ChangeDetectorRef } from '@angular/core';
import { PostType } from '../../../../models/types';
import { MainService } from '../../../../services/main.service';
import { GalleryItem, ImageItem } from '@ngx-gallery/core';

@Component({
  selector: 'app-cubaness-gallery',
  templateUrl: './gallery.component.html',
  styleUrls: ['./gallery.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class GalleryComponent implements OnInit {
  @Input() id = '';
  public isDataReady = false;
  cameraImages: GalleryItem[];

  constructor(
    private service: MainService,
    private cd: ChangeDetectorRef
  ) {
  }

  ngOnInit() {
    if ( this.id ) {
      this.service.getPostById(this.id, false, '', PostType.GALLERY)
        .subscribe(response => {
          if ( response.total ) {
            this.cameraImages = response.posts[0].custom_fields.images.map(image => {
              return new ImageItem({
                src: image.url,
                thumb: image.url,
                title: image.title
              });
            });
            this.isDataReady = true;
            this.cd.markForCheck();
          }
        });
    }
  }

}

View

<div class="ml-auto mr-auto my-5 py-5" *ngIf="!isDataReady">
  <app-loading [loadingData]="true"></app-loading>
</div>
<ng-container *ngIf="isDataReady">
  <div>
    <gallery [id]="id" [gallerize]="id" [items]="cameraImages"></gallery>
  </div>
</ng-container>
MurhafSousli commented 4 years ago

Try this way

images$: Observable<GalleryItem[]>;
 // ..
this.images$ = this.service.getPostById(this.id, false, '', PostType.GALLERY).pipe(
      filter(res=> !!res.total),
      map(res => {
        return response.posts[0].custom_fields.images.map(image => {
          return new ImageItem({
            src: image.url,
            thumb: image.url,
            title: image.title
          });
      })
    );
<ng-container *ngIf="images$ | async as images; else loading">
  <div>
    <gallery [id]="id" [gallerize]="id" [items]="images"></gallery>
  </div>
</ng-container>

<ng-template #loading>
  <div class="ml-auto mr-auto my-5 py-5">
    <app-loading [loadingData]="true"></app-loading>
  </div>
</ng-template>
yuniers commented 4 years ago

@MurhafSousli Thank you a lot for you code.

I put it on my app but too much recursion is present.