简体   繁体   中英

how to access objects gotten from service in the component?

When I tried to access atoms using 'this.atoms' in the searchAtoms, it returns "TypeError: Cannot read property 'length' of undefined". I am thinking atoms are all set because *ngFor is working well. There is some hidden logic behind subscribe? If someone knows about this, could you give some clues? And, also another question, when I defined getAtoms method with a parameter, atom name value gotten from input field in the atom.service.ts like this.service.getAtoms(newAtom). But I get "A parameter proerty is only allowed in a constructor implementation". I think I can't use this way. Could you anybody recommend a desirable way for this?

app.component.ts

import {Component} from 'angular2/core';
import {Router} from 'angular2/router';
import {AtomService} from './service/atom.service';
import {Atom} from './datatype/Atom';

@Component({
    selector: 'my-app',
    template: `<br>
    <input #atomname value='atom1'>
    <button (click)=searchAtoms(atomname.value)>Search Atoms</button>  
    <br><br>
    <ul>
        <li *ngFor="#atom of atoms">
            {{atom.id}} - {{atom.name}}
        </li>
    </ul>`,
    providers: [ConceptService]
})


export class AppComponent {

    atoms: Array<Atom>;

    constructor(private service : AtomService) {

    }

    searchAtoms(newAtom: string) {
        console.log("searchAtoms\t" + newAtom);
        if (newAtom) {
            this.service.getAtoms(newAtom).subscribe(data => this.atoms = data);
            console.log(this.atoms.length);
        }
    }
}

atom.service.ts

import { Injectable }     from 'angular2/core';
import { Http, Response, URLSearchParams, Headers } from 'angular2/http';
import 'rxjs/add/operator/map';
import {Atom} from '../datatype/Atom';

@Injectable()
export class ConceptService {

  constructor(private http: Http) {
    this.http = http;
  }

  getAtoms(private newAtom: string) {
    return this.http.get('api/atoms.js')
    .map( (responseData) => {return responseData.json()})
    .map( data => {
        let results:Array<Atom> = [];
        for (var i = 0; i < data.result.length; i++) {
            results.push(new Atom(data.result[i].id, data.result[i].name));
        }
        return results;
    });
  }
}

The Http service returns an Observable and you subscribe to it. This is an asynchronous operation but you are trying to access the data before it arrives from the server. If you move your console.log inside of your subscribe callback it will work.

this.service.getAtoms(newAtom).subscribe(data => {
  this.atoms = data;
  console.log(this.atoms.length);
});

For your second question you just need to drop the private keyword.

getAtoms(newAtom: string) { }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM