6

i want to make a post resquest using angular 5, but it gives me an error : here is the code :

service.ts

import { Injectable } from '@angular/core';
import { Response, Headers } from '@angular/http';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { catchError, retry } from 'rxjs/operators';
//Grab everything with import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

import { User } from '../iterface';

import { HttpHeaders } from '@angular/common/http';

const httpOptions = {
   headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Authorization': 'my-auth-token'
   })
};

@Injectable()
export class DataService {

_baseUrl: string = '';

constructor(private http: HttpClient) {
    this._baseUrl = "http://sso-app-bonita.qualif.dauphine.fr:8080/bonita/";
}

addUser(user: User): Observable<User> {
    return this.http.post<User>(this._baseUrl, '/API/identity/user', httpOptions)
        .pipe(
        catchError(this.handleError('addHero', user))
        );
}


private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
        // A client-side or network error occurred. Handle it accordingly.
        console.error('An error occurred:', error.error.message);
    } else {
        // The backend returned an unsuccessful response code.
        // The response body may contain clues as to what went wrong,
        console.error(
            `Backend returned code ${error.status}, ` +
            `body was: ${error.error}`);
    }
    // return an ErrorObservable with a user-facing error message
    return new ErrorObservable(
        'Something bad happened; please try again later.');
};

}

component.ts

heroes :[];

createUser() {
  this.dataService.addUser(this.user2)
  .subscribe(hero => this.heroes.push(hero));
}

it gives me an error :

TypeError: this.selector is not a function Stack trace: CatchSubscriber.prototype.error@webpack-internal:///../../../../rxjs/_esm5/operators/catchError.js:108:26

5 Answers 5

9

Let's give this a try...

//FileName: login.service.ts
import { Injectable } from '@angular/core';
import { HttpParams, HttpClient, HttpHeaders } from '@angular/common/http';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';

import { catchError, retry } from 'rxjs/operators';

@Injectable()
export class LoginService {
    private _loginUrl = 'http://1.2.3.4/signin'; //the api url where we need to make a call
    constructor(private _http: HttpClient) {} //this initialized the HttpClient which we use to do a post or get call

    //setting body of the parameters to send via post 
    private body = new HttpParams()
    .set('username', 'onetap')
    .set('password', '123456');

    checkLogin(){
         return this._http.post(this._loginUrl,
            this.body.toString(),
            {
              headers: new HttpHeaders()
                .set('Content-Type', 'application/x-www-form-urlencoded')
            }
          )
        .pipe(
        catchError(this.handleError) // then handle the error
       );
    }
  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  }
}

Let me explain this now... First things first... go and refer this link , which is the basic guide with live example on how setup httpclient and use it.

In this code lets start with imports:
Injectable: A decorator which will help you inject this service into any component you need. Just import then set it in @Component providers then create instance of it in constructor and use it using this.

HttpParams: Set the parameter or data to send for 'Content-Type': 'application/x-www-form-urlencoded'.

HttpClient: This is the module using which we implement the get, post put methods.

throwError, catchError, retry: This could be your homework to research on.

checkLogin() implements the post method. Using HttpParams we create the body instance and pass it to checkLogin.
Post request will take 3 parametes. 1. Url, 2. Data or body to send, 3. Optional headers.

Now we call this checkLogin from our components onSubmit method given below

    onSubmit() {
        this.loginService.checkLogin()
        .subscribe(resp => {
            this.user = {
                username: resp['username'],
                email: resp['email'],
                password: resp['password']
            };
            console.log(this.user);//Check if we are getting data from server
        });
                

    }

After all this is done. If you are getting a CORS issue which you might get if you are on local host or a different server. Use the code below

This is at the server end code

do

npm install cors --save

and just add these lines in your main file where your request is going.

const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
Sign up to request clarification or add additional context in comments.

2 Comments

Is this solution an improvement on any of the other answers? How? It would be really helpful if you could edit your answer and explain how it solves the OP's question and how it improves other answers. Thanks!
@jayelston I am updating it with a perfect working code!
8

try using this in your service.ts

import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);

addUser(user : User){
    return this.http.post(this._baseUrl + '/API/identity/user',user,{ headers: headers}).map((response: Response) =>{
    console.log (response.json());
    })
}

here you need to send user interface to HTTP post. and map your response.

in ts file

createUser(){

 this.dataService.addUser(this.user2).subscribe(data => {alert("Succesfully Added Product details")},Error => {alert("failed while adding product details")})
}

7 Comments

that works , but how can send httpOptions in the header ?
thanks but actually, i kept the code like that this.http.post(this._baseUrl + 'loginservice',httpOptions) ..., i passed what i want in the httpOptions, but i sent the request to the server api, i got this message : Cross-Origin Request blocking: Same Origin policy does not allow to check the remote resource located on sso********************:8080/api/loginservice . Reason: The CORS header "Access-Control-Allow-Origin" is missing.
This a problem with the CORS configuration on the server. It is not clear what server are you using.. which server language you are using?
java , i'm just consuming the the app's APIs, what is the solution please?
yes, brother but if you are adding headers and they have not allowed cross allow origin to your localhost you cannot access api's data.this is a general problem and you can get any solution on this on StackOverflow and google too. if this helped you don't forget to upvote so this can be helpful to others. any discussion we can continue to chat. happy coding.
|
4

you are missing the data you want to post it should be like this eg:-

this.http.post("https://reqres.in/api/users/2'",
    {
      "name": "morpheus",
      "job": "leader"
    })
    .subscribe(
        (val) => {
            console.log("POST call successful value returned in body", 
                        val);
        },
        response => {
            console.log("POST call in error", response);
        },
        () => {
            console.log("The POST observable is now completed.");
        });
}

In your case this.http.post<User>(this._baseUrl+'/API/identity/user', <yourdata> httpOptions)

also you might want to take a look at rxjs imports

import { catchError, map } from "rxjs/operators";

8 Comments

@Newme its just a example in your case you have not passed the data you want to post you have passed three parameters to the post the link but no data check the in your case in the answer. did you add the rxjs imports
thaks but i changed the link into this.http.post<User>(this._baseUrl+'API/identity/user', user , httpOptions) but i got the same error
its already added import { catchError, retry } from 'rxjs/operators';
if you look at the code you have added it twice one up top and other at bottom
i kept just import { catchError, retry } from 'rxjs/operators'; but the same error
|
2

It's Really Very Simple, follow as I have jotted down.

//Import Headers

import { HttpClient, HttpHeaders } from '@angular/common/http';

//Create Headers

const ParseHeaders = {
 headers: new HttpHeaders({
  'Content-Type'  : 'application/x-www-form-urlencoded'
 })
};

//Create Post request

let _URL = "www.example.com/postdata";
let FormData = "FormData1="+Data1+"&FormData2"+Data2
this.httpClient.post(_URL,FormData,ParseHeaders).subscribe((res) => {
 console.log(res);
});

While Receiving in server side, if it's PHP then Use $_POST['FormData1']; This Really works.

Comments

0

At first create a component service:

ng g s <<name of component service>>

Then import the headers of httpClient:

import { HttpClient, HttpHeaders } from '@angular/common/http';

At second into .ts component service inject the httpClient object into the constructor:

constructor(private http:HttpClient) { }

Stay in component service and create a function that it will get your information into the normal component:

 public saveUser(data)
       {
        const httpOptions = {
          headers: new HttpHeaders({
            'Content-Type':  'application/json',
           // 'Authorization': this.jwt
          })
        };

        return this.http.post(this._baseUrl+'/API/identity/user',data,httpOptions);
       }

Into the normal component just add this it will be work fine:

 constructor(private user:NameofComponentService) { }
     this.user.saveUser(this.liste).subscribe(data=>{  
    //console.log(data);

  },err=>{
    console.log(err.error.message);
  })

Comments