2

I have a slight issue:

Error: (SystemJS) Maximum call stack size exceeded(…)

I have a component where I import another module: Here is videos.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { VideosComponent } from './videos.component';
import { EditorModule, SharedModule, ButtonModule } from 'primeng/primeng';
import { GalleryModule } from '../../components/gallery/gallery.module';


@NgModule({
  imports: [CommonModule, SharedModule, EditorModule, SharedModule, ButtonModule,  GalleryModule],
  declarations: [VideosComponent],
  exports: [VideosComponent],
  providers: []
})
export class VideosModule { }

As you can see I am importing the Gallery Module. If I remove this then the error goes away. Lets continue down the rabbit hole.

Here is the gallery gallery.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { ViewerComponent } from '../viewer/viewer.component';
import { GalleryComponent } from './gallery.component';

@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule],
  declarations: [GalleryComponent, ViewerComponent],
  exports: [GalleryModule],
  providers: []
})
export class GalleryModule { }

Here is the gallery.component.ts

import {Component, NgZone, ViewChild, ElementRef} from '@angular/core';
import {Http, Response} from '@angular/http';
import { ViewerComponent } from '../viewer/viewer.component';
import 'rxjs/Rx';


interface IImage {
  url: string;
  thumbnail: string;
  date: string;
  width: number;
  height: number;
}


@Component({
  selector: 'sd-gallery',
  templateUrl: 'gallery.component.html',
  styleUrls: ['gallery.component.css']
})
export class GalleryComponent {

  @ViewChild('galleryContainer') galleryContainer: ElementRef;
  @ViewChild('asyncLoadingContainer') asyncLoadingContainer: ElementRef;

  thumbnailBasePath = 'assets/img/gallery/preview_xxs/';
  currentIdx: number = 0;
  galleryBasePath: string = 'assets/img/gallery/';
  showBig: boolean = false;
  images: any[] = [{ url: '' }];
  gallery: any[] = [];
  imgIterations = 1;
  allImagesLoaded = false;


  // TypeScript public modifiers
  constructor( private _ngZone: NgZone, private http: Http ) {

  }


  private ngAfterContentInit() {
    this.fetchDataAndRender();
  }

  private fetchDataAndRender() {
    this.http.get(this.galleryBasePath + 'data.json')
      .map((res: Response) => res.json())
      .subscribe(
      data => {
        this.images = data;
        this.render();
      },
      err => console.error(err),
      () => undefined);
  }

  private render() {
    let tempRow = [this.images[0]];
    let rowIndex = 0;
    let i = 0;

    for (i; i < this.imgIterations && i < this.images.length; i++) {
      while (this.images[i + 1] && this.shouldAddCandidate(tempRow, this.images[i + 1])) {
        i++;
      }
      if (this.images[i + 1]) {
        tempRow.pop();
      }
      this.gallery[rowIndex++] = tempRow;

      tempRow = [this.images[i + 1]];
    }

    this.scaleGallery();

    if (i >= this.images.length) {
      this.allImagesLoaded = true;
    } else {
      this.checkForAsyncReload();
    }
  }

  private shouldAddCandidate(imgRow: IImage[], candidate: IImage): boolean {
    let oldDifference = this.calcIdealHeight() - this.calcRowHeight(imgRow);
    imgRow.push(candidate);
    let newDifference = this.calcIdealHeight() - this.calcRowHeight(imgRow);

    return Math.abs(oldDifference) > Math.abs(newDifference);
  }

  private calcRowHeight(imgRow: IImage[]) {
    let xsum = this.calcOriginalRowWidth(imgRow);

    let ratio = this.getGalleryWidth() / xsum;
    let rowHeight = imgRow[0].height * ratio;

    return rowHeight;
  }

  private scaleGallery() {
    this.gallery.forEach((imgRow) => {
      let xsum = this.calcOriginalRowWidth(imgRow);

      if (imgRow !== this.gallery[this.gallery.length - 1]) {
        let ratio = this.getGalleryWidth() / xsum;

        imgRow.forEach((img: any) => {
          img.width = img.width * ratio;
          img.height = img.height * ratio;
        })
      }
    })
  }

  private calcOriginalRowWidth(imgRow: IImage[]) {
    let xsum = 0;
    imgRow.forEach((img) => {
      let individualRatio = this.calcIdealHeight() / img.height;
      img.width = img.width * individualRatio;
      img.height = this.calcIdealHeight();
      xsum += img.width + 1;
    });

    return xsum;
  }

  private calcIdealHeight() {
      return (this.getGalleryWidth() / 8) + 70;
  }

  private openImageViewer(img: any) {
    this.showBig = undefined;
    this.showBig = true;
    this.currentIdx = this.images.indexOf(img);
  }

  private getGalleryWidth() {
    if (this.galleryContainer.nativeElement.clientWidth === 0) {
      // IE11
      return this.galleryContainer.nativeElement.scrollWidth;
    }
    return this.galleryContainer.nativeElement.clientWidth;
  }

  private checkForAsyncReload() {
    if (!this.allImagesLoaded) {
      var loadingDiv: any = this.asyncLoadingContainer.nativeElement;

      var elmTop = loadingDiv.getBoundingClientRect().top;
      var elmBottom = loadingDiv.getBoundingClientRect().bottom;

      var isVisible = (elmTop >= 0) && (elmBottom <= window.innerHeight);

      if (isVisible) {
        this.imgIterations += 5;
        this.fetchDataAndRender();
      }
    }
  }

  private onClose() {
    this.showBig = false;
  }

  private onResize() {
    this.render();
  }


}

I will not include with the viewer part because even if I remove it from the gallery html/module I still get the same issue.

Thanks all!

1
  • Hey Pete, I realized you posted some of my code about my Angular 2 image gallery here on Stackoverflow (github.com/BenjaminBrandmeier/ng2imggallery). It seems like you found help already, thanks to Stefan. If you experience more problems feel free to create an issue on GitHub and I'm happy to assist. Commented Dec 30, 2016 at 23:16

2 Answers 2

1

I see two mistakes in your GalleryModule, one of them is probably causing the error you are getting.

First

BrowserModule should only be imported in your root module. (most commonly, this is AppModule) You should import CommonModule instead because that's probably all you need in GalleryModule. (CommonModule contains common directives like *ngIf and *ngFor)

Second

Remove GalleryModule from its exports:

exports: [GalleryModule]

Why would you export GalleryModule from GalleryModule itself? This line is already doing all the work:

export class GalleryModule { }

If I had to bet, I'd say this is what's causing the error.

Sign up to request clarification or add additional context in comments.

3 Comments

@Pete That's because your templateUrl's are incorrect, you need to provide full path, for example templateUrl: 'app/gallery/gallery.component.html', name of the html file itself is not enough, component has to know where to look for it exactly.
All my other components work this way, buy having the components html in the same folder and referenced the same way with the template Url. Each component has its own folder to store all the files relating to it.
@Pete Well, that's a whole another problem, you should google and find out what it is. The problem you asked about is fixed.
0

When I got this error, it was caused by including the prototype.js library on my web page. After I removed prototype, my Angular 2 app loaded successfully.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.