Service variable comes as UNDEFINED in Angular Component 2

Asked

Viewed 734 times

1

I’m not getting a variable from a service at 2. I have companies-index.component.ts and companies-crud.service.ts. I would like to take a service variable in Component but it always comes as UNDEFINED, but if I run within the service some function it returns normal.

I’m doing a separate archery crud to be better organized. Follows the codes

companies-index.component.ts

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

import { EmpresasCrudService } from './services/empresas-crud.service';

import {PagerService} from './services/pagination';

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

    constructor(private dataService: EmpresasCrudService, private pagerService: PagerService) {

  }
     // array of all items to be paged
    public allItems: any[];

    // pager object
    pager: any = {};

    // paged items
    pagedItems: any[];

    _page = 1;
    _mostrar = 1;
    _qtd;
    _loading = false;
    Items;

    getEmps(page: number, mostrar:number){


        this.dataService.getEmpresas(page, mostrar);
        console.log(this.dataService.allItems);

    }



    ngOnInit(){
      this.getEmps(this._page,this._mostrar);

    }




}

Empresa-crud.service.ts

import { Injectable, Input, Output } from '@angular/core';
import { HttpService } from '../../../shared/services/http.service';
import {Observable} from 'rxjs/Rx';

// Import RxJs required methods
import 'rxjs/add/operator/map';

import {Empresa} from '../models/empresas';
import {ListResult} from '../models/pagination';

//import 'rxjs/add/operator/catch';

@Injectable()
export class EmpresasCrudService {


    constructor(private _http: HttpService) {
    }

    //Url
    _endpoint_url: string = 'http://www.sysferaser.com/data/';
    //Itens a pegar da API
    allItems: any[];
    //Quantidade de itens totais da API
    _qtd;

    //faz a requisição
    getHttpEmpresas(page:number, mostrar:number): Observable<ListResult<Empresa>> {
        return this._http.httpGet(this._endpoint_url + mostrar + "?page=" + page)
            .map(response => response.json());
    }

    //Atribui os dados nas variáveis allItems e _qtd
    getEmpresas(page:number, mostrar:number){
        this.getHttpEmpresas(page, mostrar)
            .subscribe(
                people => {
                    this.allItems = people.data,
                    this._qtd = people.total
                },
                error => console.error('Error: ' + error),
                () => console.log('Completed!')

            );
    }


}

1 answer

1


I suggest a change in your coding. You are making all the ajax request within your service. It may be, but I prefer it is that part of the process is carried out within the component. This way you can make Forks, better manipulate the request among other situations.

I suggest you change your coding to the following:

companies-index.component.ts

import { Component, OnInit } from '@angular/core';
import { EmpresasCrudService } from './services/empresas-crud.service';
import {PagerService} from './services/pagination';

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

    constructor(private dataService: EmpresasCrudService, private pagerService: PagerService) {}

    // array of all items to be paged
    public allItems: any[];

    // pager object
    pager: any = {};

    // paged items
    pagedItems: any[];

    _page = 1;
    _mostrar = 1;
    _qtd;
    _loading = false;
    Items;

    getEmps(page: number, mostrar:number){
        this.dataService.getHttpEmpresas(page, mostrar).subscribe(result => {
              this.allItems = people.data,
              this._qtd = people.total          
        },
            error => console.error('Error: ' + error),
            () => console.log('Completed!'));
    }

    ngOnInit(){
      this.getEmps(this._page,this._mostrar);
    }

}

Empresa-crud.service.ts

//import 'rxjs/add/operator/catch';

@Injectable()
export class EmpresasCrudService {


    constructor(private _http: HttpService) {
    }

    //Url
    _endpoint_url: string = 'http://www.sysferaser.com/data/';
    //Itens a pegar da API
    allItems: any[];
    //Quantidade de itens totais da API
    _qtd;

    //faz a requisição
    public getHttpEmpresas(page:number, mostrar:number){
        return this._http.httpGet(this._endpoint_url + mostrar + "?page=" + page)
            .map(response => response.json());
    }

}

This will work well for you. You will have access to ajax request returns and all your variables will be populated. Up front when you need to make multiple requests where one depends on the other, you can use Fork and everything is easier.

I didn’t understand very much why you created the service "Shared/services/http.service". But anyway.. this should work there.

This approach of mine will work for you, but if you really need the structure that you mentioned earlier, put there that we look together for the solution. hug!

  • Hello Renato, when I did this part of the system I did according to what you posted and worked beauty, but it is that I found it more interesting to put all the requisition part in a service ... I believe that it will not work anyway .... from what I read, it is because of the Observable that makes the request, since it is not given time to set the variable, IE, in my Komponent the variable is called before it sets in the service ... would it be better to do with Promises? I’m new in angular, I come from php

  • Exactly that. You make an ajax request within the service and try to access the data within the component. But this ajax request takes some time and the component tries to access the data before the request returns the data. In this scenario you will need to use the angular 2 solver. The solver is the way you stop something until another one is solved. In your case you need to stop rendering the component until the service completes the ajax request.

  • I get it. And by my Komponent you have an idea of how I do it?

  • In your case I do not know how it will resolve, because all your ajax request is within the service. I structure my project a little different from you. I made a CRUD at Angular 2 and I use the resolve. You can look there and try to adapt your reality. In my case I needed to use the resolve, because I wanted that when editing a record, the form component was only loaded after the data had already been returned by the request. so there wasn’t that problem of when the guy was going to edit a record, the form was loaded blank to then get the data

  • take a look at my code I posted in git: https://github.com/renatosistemasvc/CRUD-agunlar-2/blob/master/app/admin/loja/loja-form/form.component.ts. See what can be done for you.

  • If you want to look at the whole crud project: https://github.com/renatosistemasvc/CRUD-agunlar-2 I created and made available to help the community. Anything, at night with more time I help you structure the solution in your project. hug.

  • Beauty Renato, I’ll take a look and we’ll talk. Thank you

  • Renato, nice example you left on github, It is giving to learn a lot... Regarding the request I did as you said, by Component, it was beautiful, but I was doing the SERCH and there was an error that I think that with RESOLVE we can solve, take a look at the new question and see if you can help me:

  • http://answall.com/questions/168005/problema-ao-visualizar-dados-no-template-component-no-angular-2

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.