简体   繁体   中英

.subscribe in Angular 2 to post data from a component to server via a service

I have a question regarding how observables work in Angular2 .. I am currently using the following

@angular/cli: 1.0.0
node: 6.10.0
os: win32 x64

I have a addUser component which uses a method of user service to post data to the server. I am able to achieve this but have a question on whats happening when the component file sends the data to the service method. I have imported the required packages. Below is the method which sends form data to a service method

addUser.component.ts

export class AddUser{

    addUserForm:FormGroup;
    value:any;
    constructor(private userService: UserService,private formBuilder: FormBuilder) {

        this.addUserForm = this.formBuilder.group({
          name:['',Validators.required],
          age:['',Validators.required],
          email:['',Validators.required]
        });

    }

    submit(value){

        this.userService.addUser(value).subscribe(data => {
         // refresh the list
         console.log(data)
         return true;
       },
       error => {
         console.log(error);
        });

    }

}

Below is method used in the service to send the request to the server

user.service.ts

import {Injectable} from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import 'rxjs/add/operator/cache';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs';

@Injectable()
export class UserService{

    _userInfoData: Observable<any>;
    private addUserUrl = 'http://localhost:8080/addUser'; 

    constructor(private http: Http){ }

  addUser(body: Object): Observable<any>{
    console.log(body)
    let bodyString = JSON.stringify(body)
    let headers      = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
    let options       = new RequestOptions({ headers: headers }); // Create a request option

    return this.http.post('http://localhost:8080/addUser', body, options) // ...using post request
             .map((res:Response) => res.json()) // ...and calling .json() on the response to return data
             .catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any

  }

}

My question is that when i remove the .subscribe from the submit method in addUser.component.ts the request calls the service method addUser(body: Object): Observable<any> but the service method does not post to the server.

addUser.component.ts

submit(value){

        this.userService.addUser(value)

    }

Could anyone please help me understanding what is the concept behind this

Update :

@Denko : You are correct it is not calling both the functions but only the error

submit(value){

        this.userService.addUser(value).subscribe(data => {
         // refresh the list
         console.log(data)
         return true;
       },
       error => {
         console.log(error);
        });

    }

This is what gives me the error TypeError:error.json is not a function

Update 2

@Denko ... thanks for helping me out here ... Below is the component file with the class.

addUser.component.ts

export class AddUser{
@HostBinding('@routeAnimation') routeAnimation = true;
    @HostBinding('style.display')   display = 'block';
    addUserForm:FormGroup;
    value:any;
    constructor(private userService: UserService,private formBuilder: FormBuilder) {

        this.addUserForm = this.formBuilder.group({
          name:['',Validators.required],
          age:['',Validators.required],
          email:['',Validators.required]
        });

    }

    submit(value){

        this.userService.addUser(value).subscribe(data => {
         // refresh the list
         console.log(data)
         return true;
       },
       error => {
         console.log(error);
        });

    }

}

Below is the service file which is used to make the ajax request to the server

user.service.ts

import {Injectable} from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import 'rxjs/add/operator/cache';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs';

@Injectable()
export class UserService{

    _userInfoData: Observable<any>;
    private addUserUrl = 'http://localhost:8080/addUser'; 

    constructor(private http: Http){ }

  addUser(body: Object): Observable<any>{
    console.log(body)
    let bodyString = JSON.stringify(body)
    let headers      = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
    let options       = new RequestOptions({ headers: headers }); // Create a request option

    return this.http.post('http://localhost:8080/addUser', body, options) // ...using post request
             .map((res:Response) => res.json()) // ...and calling .json() on the response to return data
             .catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any

  }

}

Whenever i hit the service method the request is passed on to the server correctly and i am able to create a user but it always enters the error block and throws the below error ....

TypeError:error.json is not a function

I would like to point out that the catch block in the service method is not called until the server is not available but the error block inside the component class is always called even if the request goes through to the server ..... What am i missing or doing incorrectly here

So, as short as possible: Imagine that an Observable is a person which talks only when there is someone listening. For someone to "listen" on the observable, someone else needs to call .subscribe() on it. If there are no subscribers (no listeners), the Observable will not do anything.

In your case, that addUser function is returning an Observable on which someone else can subscribe. So your submit function should be like this

this.userService.addUser(value).subscribe(data => { console.log("use data here"); }, err => { console.log("check if any err"); })

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