BJBlackovic
BJBlackovic

Reputation: 1

Working with HTTP-responses in angular2

I'm working on web-app with authorization via JWT and Angular 2. I've Nodejs/express server with API and client-side on Angular2. So, my server answers GET request correctly and gives data like this:

{ "success": true, "user": { "_id": "5a6ef70edb04dd29e24bb03b", "email": "danko", "username": "ivan" } }

Next, here is my auth.service.ts. Functions createAuthenticationHeaders() and getProfile() takes part in handling HTTP responses:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpRequest, HttpResponse, HttpParams} from '@angular/common/http';
import { Http, Headers, RequestOptions} from '@angular/http'; // Http, Headers, RequestOptions
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {

  domain = "http://localhost:8080";
  authToken;
  user;
  options;

  constructor(
    private http: HttpClient,
    private httplegacy: Http) {  }

  createAuthenticationHeaders() {
    this.loadToken();
    this.options = new RequestOptions({
      headers           : new Headers({
        'Content-Type'  : 'application/json',
        'authorization' : this.authToken
      })
    });
  }

  loadToken() {
    this.authToken  = localStorage.getItem('token');

  }

  registerUser(user) {
    return this.http.post(this.domain + '/authentication/register', user);
  }

  loginUser(user) {
    return this.http.post(this.domain + '/authentication/login', user);
  }


  storeUserData(token, user) {
    localStorage.setItem('token', token);
    localStorage.setItem('user', JSON.stringify(user));
    this.authToken = token;
    this.user = user;
  }

  getProfile() {
    this.createAuthenticationHeaders();
    return this.httplegacy.get(this.domain + '/authentication/profile', this.options);
  }
}

Also, here is my profile.component.ts:

import { Component, OnInit } from '@angular/core';
import { AuthService} from '../../services/auth.service';

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

  username;
  email;

  constructor(
    private authService: AuthService

  ) { }

  ngOnInit() {
      this.authService.getProfile().subscribe(profile => {
      console.log(profile);
      this.username = profile.user.username;
      this.email    = profile.user.email;
    })

  }

} 

Expected behavior of these lines of code: after handling server's response with user's data with auth.service.ts(mainly createAuthenticationHeaders() and getProfile() functions), user's data is transmitted to profile.component.ts to show it on web-page using next code:

<h2 class="page-header">Profile Page</h2>
<ul class="list-group">
  <li class="list-group-item">Username: {{ username }} </li>
  <li class="list-group-item">Email: {{ email }}</li>
</ul>

But, while compiling I got an error: property 'user', doesn't exist on type 'Response'. Would You like to explain why i got such error, and how to fix it?

P.S.: yep, console.log(profile) gives me such info:

Response {_body: "{"success":true,"user":{"_id":"5a6ef70edb04dd29e24bb03b","email":"danko","username":"ivan"}}", status: 200, ok: true, statusText: "OK", headers: Headers, …}
headers:Headers {_headers: Map(1), _normalizedNames: Map(1)}
ok :    true
status   :    200
statusText    :    "OK"
type    :    2
url    :    "http://localhost:8080/authentication/profile"
_body    :    "{"success":true,"user":{"_id":"5a6ef70edb04dd29e24bb03b","email":"danko","username":"ivan"}}"
__proto__    :    Body
constructor    :    ƒ Response(responseOptions)
toString    :    ƒ ()
__proto__    :
Object

But how can I get data from _body field of response?

P.S.: code for router from server side:

router.get('/profile', (req, res) => {
    User.findOne({ _id: req.decoded.userId }).select('username email').exec((err, user) => {
        if (err) {
            res.json({ success: false, message: err });
        } else {
            if(!user) {
                res.json({ success: false, message: 'User not found'});
            } else{
                res.json({ success: true, user: user });
            }
        }
    });
});

Upvotes: 0

Views: 60

Answers (3)

Sumeet Kale
Sumeet Kale

Reputation: 365

Try this

ngOnInit() {
      this.authService.getProfile().subscribe(profile => {
      console.log(profile);
      let p = profile.json();
      this.username = p.user.username;
      this.email    = p.user.email;
    })

  }

Upvotes: 0

BJBlackovic
BJBlackovic

Reputation: 1

Update: @messerbill's was 50/50 correct. Such construction works:

this.authService.getProfile().subscribe(profile => {
  console.log(profile);
  let p = JSON.parse(profile._body)
  this.username = p.user.username;
  this.email    = p.user.email;
})

My web-page got user's info and show it in correctly, but an error left and i've to comment these lines of code to compile and run my application, and uncomment after to see user's info on webpage. An error message: property '_body' does not exists on type 'Response'. So, at this moment i've no idea how it works with an error and how to create really correct structure.

Upvotes: 0

messerbill
messerbill

Reputation: 5629

you try to read your data directly from the Response Object of express. You need smth like:

this.authService.getProfile().subscribe(profile => {
  console.log(profile);
  let p = JSON.parse(profile._body)
  this.username = p.user.username;
  this.email    = p.user.email;
})

This will take the JSON string from the body of your HTTP Response and make it an accessible object.

NOTE:

It would be much better to tell the server to answer with a standard json due to this is web standard nowadays.

Upvotes: 1

Related Questions