Ricardo Silva
Ricardo Silva

Reputation: 388

Angular 2 View not displaying data from Webservice

I have a Web Service which is providing some user data (this is Java backend) and I have an Angular component:

import { Component,state,style,animate,transition, trigger, keyframes, 
OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/pluck';

import { IUser } from './user.interface';

@Component({
  moduleId: module.id,
  selector: 'user-cmp',
  templateUrl: 'user.component.html'
})
export class UserComponent {

  user: Observable<IUser>;

  errorMessage: string;

  constructor(private _userService: ActivatedRoute){
    this.user = _userService.data.pluck('user');
  }

}

I am using a Resolver:

import { Resolve } from '@angular/router';
import { Observable } from 'rxjs/Observable'
import { Observer } from 'rxjs/Observer';

import { IUser } from './user.interface';
import { UserService } from './user.service';
import {Injectable} from "@angular/core";

@Injectable()
export class UsersResolver implements Resolve<IUser> {

  constructor (private _userService: UserService) {}

  resolve(): Observable<IUser>{
    return this._userService.getUser();
  }
}

Resolver is using a service:

import {Injectable} from "@angular/core";
import { Http, Response } from "@angular/http";

import { IUser } from './user.interface';

import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class UserService {
  private _userUrl = 'http://localhost:8000/rest/users';

  constructor(private _http: Http){

  }

  getUser(): Observable<IUser>{
    return this._http.get(this._userUrl)
      .map((response: Response) => {
        return <IUser> response.json();
      })
      .do(data => console.log('All: ' + JSON.stringify(data)))
      .catch(this.handleError);
  }

  private handleError (error: Response){
    console.error(error);
    return Observable.throw(error.json().error || 'Server Error');
  }
}

And finally the View:

<div class="main-content" >
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-8">
                <div class="card" [@carduserprofile]>
                    <div class="header">
                        <h4 class="title">Edit User Profile</h4>
                    </div>
                    <div *ngIf="user" class="content">
                        <form>
                            <div class="row">

                                <div class="col-md-3">
                                    <div class="form-group">
                                        <label>Username</label>
                                        <input type="text" class="form-control" placeholder="Username" value="{{user.username }}">
                                    </div>
                                </div>
                                <div class="col-md-4">
                                    <div class="form-group">
                                        <label>Email address</label>
                                        <input type="email" class="form-control" placeholder="Email" value="{{user.password}}">
                                    </div>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-md-6">
                                    <div class="form-group">
                                        <label>Phone</label>
                                        <input type="text" class="form-control" placeholder="Phone" value="{{user.telephone}}">
                                    </div>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-md-12">
                                    <div class="form-group">
                                        <label>Type</label>
                                        <input type="text" class="form-control" disabled placeholder="User type" value="{{user.type}}">
                                    </div>
                                </div>
                            </div>
                            <button type="submit" class="btn btn-info btn-fill pull-right">Update Profile</button>
                            <div class="clearfix"></div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

The module looks like this:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { MODULE_COMPONENTS, MODULE_ROUTES } from './dashboard.routes';
import { UsersResolver } from './user/user.resolver';

@NgModule({
    imports: [
        BrowserModule,
        RouterModule.forChild(MODULE_ROUTES)
    ],
    declarations: [ MODULE_COMPONENTS ],
    providers: [ UsersResolver ]
})

export class DashboardModule{}

And also the part of the route is like this:

{ path: 'user', component: UserComponent, resolve: {user: UsersResolver} },

I didn't paste some useless parts of the code, like animations and etc. My problem is, it prints the data from the webservide using the .do in the service, but it doesn't show nothing in the View. Fields are blank.

I am using *ngIf in case of blank user data from WS.

I have no idea why and also I don't know how to implement some codes to check it in the View.

Any help will be great! Thanks in advance.

Upvotes: 4

Views: 369

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202326

The problem I see is located here:

constructor(private _userService: ActivatedRoute){
  this.user = _userService.data.pluck('user');
}

this.user is an observable so you need to subscribe it to get the value either within the component (with this.user.subscribe(...)) or in the template using the async pipe.

Perhaps you could simply leverage the snapshot for the route:

constructor(private _userService: ActivatedRoute){
  this.user = _userService.snapshot.data['user'];
}

This way the user would be a raw JS object and not an observable. So using the following should be better:

<div *ngIf="user" class="content">

Upvotes: 3

Related Questions