4

At the beginning I want to apologize for my poor English. We build the of my work rest service. On the client side it supports angular2. I am a beginner in this technology. I read that it is better to use Observable, instead of promise. I want to get a single object with user data, and unfortunately console returns an error "Can not read property ... of undefined". The documentation Angular example uses an array rather than a single object. When I use the array, there is no error, but I need to download a single object. My question is, whether it is by Observable get object and show object in template?

** service **

import { Injectable } from "@angular/core";
import { AppParameters } from "../parameters";
import { AuthHttp } from "angular2-jwt";
import { AuthService } from "./auth.service";
import { Response } from "@angular/http";
import { Observable } from 'rxjs/Observable';
import { UsersModel } from "../../models/models";
import { GroupModel } from "../../models/models";

@Injectable()

export class ProfileService {

    private userUrl: string = AppParameters.ENDPOINT_URL + "/users";
    private groupUrl: string = AppParameters.ENDPOINT_URL + '/groups';
    private wallUrl: string = AppParameters.ENDPOINT_URL + "/posts/";


    constructor(
        private authHttp: AuthHttp,
        private authService: AuthService
    ){}

    getUsers(id) : Observable<UsersModel> {
            return this.authHttp.get(this.userUrl + '/' + id + '/')
                .map(this.extractData)
                .catch(this.handleError)
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || { };
    }

    private handleError (error: any) {
        let errMsg = (error.message) ? error.message :
            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

** component **

import { Component, OnInit } from "@angular/core";
import { AppParameters } from "../../shared/parameters";
import { ProfileConfig } from "./profile.config";
import { UsersModel } from "../../models/models";
import { ProfileService } from "../../shared/services/profile.service";
import { ActivatedRoute } from "@angular/router";


@Component({
    templateUrl: AppParameters.TEMPLATE_URL + ProfileConfig.COMPONENT_NAME + '/user.html',
    providers: [ ProfileService ]
})

export class UserComponent implements OnInit {

    user : number;
    data: UsersModel;
    errorMessage: string;

    constructor(
        private profileService: ProfileService,
        private route: ActivatedRoute,
    ){}

    ngOnInit() {
        this.getUser();
        this.getData();
    }

    getUser() {
        this.route.params
            .subscribe(params => {
                this.user =+ params['id'];
            });
    }

    getData() {
        this.profileService.getUsers(this.user)
            .subscribe(
                data => this.data = data,
                error => this.errorMessage = <any>error
            );
    }
}

model

export class UsersModel {
    id: number;
    username: string;
    email: string;
    user_profile: UserProfileModel;
}

class UserProfileModel {
    city: string;
    status: string;
    about: string;
}

4 Answers 4

1

You could use the () complete functionality here and check within your template if the observer completed.

// component
observer.subscribe(
   value => this.obj = value,
   (errData) => { this.renderErrors() },
   () => {
       this.variableFilledWhenDone = true;
   }
);

<!-- template -->
<div *ngIf="ariableFilledWhenDone">
       <!-- stuff that needs to happen async -->
    <div>
Sign up to request clarification or add additional context in comments.

3 Comments

It does not fix the problem. The error disappeared, but the values are not get from service. The variable is not set to true. The idea is to retrieve the value of the object through observable. The documentation angular, for example Observable are get data only from the Table, there is nothing about the objects. That's why I wonder if it can be done
I'm sorry for the mistake, I mean not on the table, but this array. You need to get the properties of a single object instead and not with array
I would assume that you have trouble getting the data from the service itself.
0

I don't get your exact problem, but i would change this:

ngOnInit() {
    this.route.params
        .subscribe(params => {
            // route parameter changed.. lets get new data !
            this.user =+ params['id'];
            this.getData(); // do it here, cause NOW you have that id..
        });
}

4 Comments

As for the get properties are not from the table, but with the object using Observable.
What table? Please clarify your problem.. don't get your actual problem right now.. at which point are you getting that error message? post the complete error message pls..
Eh. Sorry for the mistake. The documentation Angular data get from the model array, and I need to get them from the object.
Show your template please where data: UserModel is used.
0
<h3>Hello {{ data.username }}</h3>

<p>Change yours personal data</p>

<set-user-data [data] = 'data'></set-user-data>

Comments

0

I found a solution. In the future, if someone was looking for

private extractData(res: Response) {
    let body = <UsersModel>res.json();
    return body || { };
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.