Alex
Alex

Reputation: 1250

Angular 5: ERROR TypeError: Cannot read property 'offset' of undefined

Error: ERROR TypeError: Cannot read property 'offset' of undefined

I had comic component, was working fine, but I decided to make a child component, and now it's not working. I have a parent component 'comics', and a child component 'pagination'. The comics are displayed fine, but the pagination is not working.

In the code, the console.log(this.pagination); is returning an array like ('offset': 20, 'count':1)

But pagination.component.html ir returning an error Cannot read property 'offset' of undefined so pagination is empty, has no data. So parent comics.component.ts is not sharing this variable with child.

I tried to declare pagination: Pagination; in pagination.component.ts but pagination is still empty.

So I think I'm declaring something in a wrong mode, or I should declare something I'm not declaring. I searched, and I tried to find what's missing but I did not find anything and it's still not working.

my code:

// file: pagination.ts

export class Pagination {
  offset: number;
  count: number;
}



// file: /comics/comics.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import { Comic } from '../comic';
import { Pagination } from '../pagination';
import { ComicService } from '../comic.service';

@Component({
  selector: 'app-comics',
  templateUrl: './comics.component.html',
  styleUrls: ['./comics.component.css']
})
export class ComicsComponent implements OnInit {

  comics: Comic;
  pagination: Pagination;

  constructor(
    private route: ActivatedRoute,
    private comicService: ComicService
  ) {}

  ngOnInit() {
  }

  getComics(): void {
    const offset = +this.route.snapshot.paramMap.get('offset');
    this.comicService.getComics(offset, 20)
    .subscribe(
      result => {
        this.comics = result['data']['results'];
        console.log(this.comics);

        this.pagination.offset = result['data']['offset'];
        this.pagination.count = result['data']['count'];

        console.log(this.pagination);
  }
);
  }
}


// file: /pagination/pagination.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import { Pagination } from '../pagination';

@Component({
  selector: 'app-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}


// file: comics/comics.component.html

<div *ngFor="let comic of comics">
  <h5>{{comic.title | uppercase}} </h5>
</div>

<app-pagination></app-pagination>



// file: pagination/pagination.component.html

<div>
  <h5>{{pagination.offset}}</h5>
  <span>{{pagination.count}}</span>
</div>

Versions used:

Angular CLI: 1.7.3

Node: 8.9.4

OS: darwin x64

Angular: 5.2.8

Upvotes: 0

Views: 2891

Answers (1)

bugs
bugs

Reputation: 15323

Given that these two components are in a parent-child relationship, your best option is to simply define offset and count as input properties for the child component, and pass them from the parent, like this:

comics.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import { Comic } from '../comic';
import { Pagination } from '../pagination';
import { ComicService } from '../comic.service';

@Component({
  selector: 'app-comics',
  templateUrl: './comics.component.html',
  styleUrls: ['./comics.component.css']
})
export class ComicsComponent implements OnInit {

  comics: Comic;
  offset;
  count;

  constructor(
    private route: ActivatedRoute,
    private comicService: ComicService
  ) {}

  ngOnInit() {
  }

  getComics(): void {
    const offset = +this.route.snapshot.paramMap.get('offset');
    this.comicService.getComics(offset, 20)
    .subscribe(
      result => {
        this.comics = result['data']['results'];
        console.log(this.comics);

        this.offset = result['data']['offset'];
        this.count = result['data']['count'];
  }
);
  }
}

pagination.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import { Pagination } from '../pagination';

@Component({
  selector: 'app-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {
  @Input() offset;
  @Input() count;
  constructor() { }

  ngOnInit() {
  }

}

comics.component.html

<div *ngFor="let comic of comics">
  <h5>{{comic.title | uppercase}} </h5>
</div>

<app-pagination [offset]="offset" [count]="count"></app-pagination>

pagination.component.html

<div>
  <h5>{{offset}}</h5>
  <span>{{count}}</span>
</div>

Upvotes: 1

Related Questions