16

I am posting a request and I am suppose to receive a 'success' string back as response. I am getting an HttpResponseError with the following information posted in the image below.

enter image description here

PurchaseOrderService

postPurchaseOrderCustom(purchaseOrderCustom: PurchaseOrderSaveCustom) {
 const url = `${this.localUrl}purchaseOrderCustom`;
 return this.http.post<String>(url, purchaseOrderCustom, {headers: this.header})
            .pipe(
                   catchError(this.handleError('postPurchaseOrderCustom', 'I am an error'))
                 );
  }

PurchaseOrderComponent

this.purchaseOrderService.postPurchaseOrderCustom(purchaseOrderCustom).subscribe( response => {
  console.log("Testing", response);
  },
  error => {
    console.error('errorMsg',error );   
  }

The way I am doing it is the same way its done in the documentation. Do point out to me what I am doing wrong.

error shown when I implement answer provided by @Muhammed

user3701188
  • 638
  • 3
  • 7
  • 23
  • This is angular error realted to you api respond ,http object by default try to parse you api respond it 's seen just plain text this why the throw this cand in error ,try this in you console `JSON.parse('Hi')` if you don't get my pont – Muhammed Albarmavi Jul 29 '18 at 19:26
  • Either wrap your response in quotes at the backend, or change the `responseType` to 'text' in the front end – user184994 Jul 29 '18 at 19:27
  • 1
    @user184994 what do you mean by wrap in quotes in the backend, it is already in quotes and that makes it a string. That is if I am getting you write. And what happens if you are receiving an object back – user3701188 Jul 29 '18 at 19:48
  • Yep, but you need extra quotes, something like `"\"success\"". If you receiving a valid JSON object back, there won't be any issues, it depends on what you mean when you say "an object" – user184994 Jul 29 '18 at 19:50
  • @user184994 Im using springboot as my backend and usually when you send an object it gets parsed as Json and is transformed to the corressponding Object in Angular. Thats if Im correct. So why is it different from a string object. – user3701188 Jul 29 '18 at 19:57

3 Answers3

25

This related to your api respond type ,success is not valid json format,by default HttpClient is expected json response type and try to parse it later . You can solve this by set the respond type to text like this

return this.http.post<String>(
    url,
    purchaseOrderCustom,
    { headers: this.header, responseType: 'text' }
)
    .pipe(
        catchError(this.handleError('postPurchaseOrderCustom', 'I am an error')
        ));
Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91
  • 3
    I had to add as 'json'. before it worked so if you can edit your answer so I accept it. {headers: this.header , responseType:'text' as 'json'}) – user3701188 Jul 29 '18 at 21:09
  • did you add this to make it work `responseType:'json'` – Muhammed Albarmavi Jul 29 '18 at 21:11
  • 9
    this is what I did `{headers: this.header , responseType:'text' as 'json'})` . just adding text didnt work for me. And from discussions from Github people added that to make it work – user3701188 Jul 30 '18 at 14:12
  • did you use Http or HttpClient ? – Muhammed Albarmavi Jul 30 '18 at 14:13
  • I use HttpClient, do you by the way know why this is – user3701188 Jul 30 '18 at 14:14
  • as operater is related to typescript if you remove it will work ,try this in typescript playground http://www.typescriptlang.org/play/index.html ,let c = {headers: '' , responseType:'text' as 'json'} – Muhammed Albarmavi Jul 30 '18 at 14:18
  • if you check the chrome network panel you will see that the responseType is text,you just change the default respond type from json to text as I said in my answer – Muhammed Albarmavi Jul 30 '18 at 14:22
  • Albarmaw sorry didnt get what you meant , but when I remove the as json I get a squiggly line error and it doesnt compile till I add the as json. – user3701188 Jul 30 '18 at 14:43
  • do you know the usage of as operator ? let b = '10' as number this mean '10' type is number but the b will be '10' this just related to typescript but the value still '10' but typescript will think b type is number – Muhammed Albarmavi Jul 30 '18 at 14:49
  • thiss `responseType:'text' as 'json'` you just tell typescript the type of respondType is litiral value of 'json' but the value will be 'text' @user3701188 – Muhammed Albarmavi Jul 30 '18 at 14:51
  • hope you got my point so {headers: this.header , responseType:'text'} will work and the respond type is text so will not parse your respond and you will not got the error that you use to have – Muhammed Albarmavi Jul 30 '18 at 14:52
  • I do understand, but the problem here is your code gives me an error in the file, it give a red squiggly error and it doesnt compile when I do it the way you suggested – user3701188 Jul 30 '18 at 14:54
  • and when I add the as json it works fine and I dont get an error in my console again – user3701188 Jul 30 '18 at 14:55
  • This is what it says `Argument of type '{ headers: HttpHeaders; responseType: "text"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'. Types of property 'responseType' are incompatible. Type '"text"' is not assignable to type '"json` – user3701188 Jul 30 '18 at 21:04
  • `{ headers: HttpHeaders; response Type: "text"; }` you separate the property with `;` semicolon and this is wrong just look to my answer it is `,` comma – Muhammed Albarmavi Jul 31 '18 at 00:20
  • it is the error that shows that my codes are exactly as your answer and it gives the error. I have updated a picture in the main question take a look at it and also take a look at the discussions provided in Github. `https://github.com/angular/angular/issues/18586` – user3701188 Jul 31 '18 at 18:40
  • as the github issues show this consider a bug but it 's **close** and it 's since 12 month you may consider update your angular version if it 's old @user3701188 – Muhammed Albarmavi Jul 31 '18 at 19:28
  • These are my angular dependencies so I think I am using the latest version `"@angular/animations": "^6.0.2", "@angular/common": "^6.0.2", "@angular/compiler": "^6.0.2", "@angular/core": "^6.0.2", "@angular/forms": "^6.0.2", "@angular/http": "^6.0.2"` – user3701188 Aug 01 '18 at 17:28
  • so i had to remove the cast that is in order to make your way work, can you also take of the cast so I get to approve the answer – user3701188 Aug 01 '18 at 17:47
3

Like it has already been said, this has everything to do with the response coming from your server.

In my case, I had a Spring Boot application that returned this:

return new ResponseEntity<>("Your SSN was generated successfully", HttpStatus.OK);

and this was the response I was getting on the Angular end:

{error: SyntaxError: Unexpected token Y in JSON at position 0
at JSON.parse (<anonymous>)
at XMLHtt…, text: "Your SSN was registered successfully."}

So what I did was create a custom CustomHttpResponse class in my Spring Boot application and then changed the code in my controller to this:

        ...
        CustomHttpResponse customHttpResponse = new CustomHttpResponse();
        customHttpResponse.setMessage("Your SSN was registered successfully.");
        customHttpResponse.setStatus(HttpStatus.OK.value());

        return new ResponseEntity<>(new Gson().toJson(customHttpResponse), 
                                          HttpStatus.OK);
        }

Now I'm getting this:

{message: "Your SSN was registered successfully.", status: 200}
   message: "Your SSN was registered successfully."
       status: 200

Essentially, this error occurs when Angular is expecting JSON but gets something else instead

Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132
2

I was also facing same issue while getting pdf data buffer in response and I handled it in following manner, it's working for me

server side

pdf.create(output, options).toBuffer((err: any, buffer: any) => {
            if (err) reject(err);
           response.type('pdf');
response.send(buffer);
        });

in Angular Service downloadPdf(dateRange, labs){

return this.httpClient.post(url, data,{responseType:'blob'});

} And in Component.ts file

downPdf1(){
    this.analyticService.downloadPdf(this.dateRange, this.labs).subscribe(
      res => this.extractPdf(res),
      (error:any) => throwError (error || 'Server error')
  );
  }

 extractPdf(res){
     let myBlob: Blob = new Blob([res], {type: 'application/pdf'}); 
     var fileURL = URL.createObjectURL(myBlob);
     window.open(fileURL);
 }