0

It seems my client is not capturing the response value from the server and displaying it.

Here is my component code:

export class MyComponent implements OnInit {

  data: string;

  constructor(private myService: MyService) {}

  ngOnInit() {}

  testCall() {
    this.myService.getData().subscribe(data => this.data = data);
    console.log("Data: " + this.data);
  }
}

The service code:

@Injectable()
export class MyService {

  private url = 'http://localhost:5000/myproj/api/test';

  constructor(private http: HttpClient) { }

  // Get data from the server
  getData(): Observable<string> {
    console.log("in getData() method");
    return this.http.get<string>(this.url)
      .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 new ErrorObservable('Something went wrong; please try again later.');
  };
}

The request goes to the server, and the server responds with the data in the response body, and a status code of 200, which you can see in developer tools in Internet Explorer:

enter image description here

But for some reason, when I call the service method getData(), the angular client code calls the catchError() method I defined, and prints:

Backend returned code 200, body was: [object Object]
ERROR Something went wrong; please try again later.

Why is the server returning status 200 (OK), but the Angular client is calling the catchError() method?

EDIT:

Here is my server side API code:

@RequestMapping(value = "/test", method = RequestMethod.GET, produces = "text/plain")
    public String testApi(HttpServletRequest request) {

        System.out.println("in /test");

        String response = "my response";

        return response;
    }
Kingamere
  • 9,496
  • 23
  • 71
  • 110
  • 2
    Do a `body was ${JSON.stringify(error.error)}` so that you can actually get the error message the server is sending back inside your catch. – Ryan C May 31 '18 at 16:45
  • @RyanC Here is the error that code returned: `{"error":{"description":"Invalid character","number":-2146827274,"stack":"SyntaxError: Invalid character\n at onLoad (eval code:2290:25)\n at ZoneDelegate.prototype.invokeTask (eval code:419:13)\n at onInvokeTask (eval code:4941:17)\n at ZoneDelegate.prototype.invokeTask (eval code:419:13)\n at Zone.prototype.runTask (eval code:188:21)\n at ZoneTask.invokeTask (eval code:495:17)\n at invokeTask (eval code:1536:9)\n at globalZoneAwareCallback (eval code:1562:17)"},"text":"my reponse"}` – Kingamere May 31 '18 at 16:50
  • 2
    So your javascript you've listed above is firing correctly. The HTTP call is coming back with an error, so it is entering into that code block. I do see that you have a `text` object in your response, but until you fix the backend problem of returning an error, it will always enter into the catchError function. – Ryan C May 31 '18 at 16:54

3 Answers3

2

The Response Body is not proper JSON format, hence the "Invalid character" error which is produced from the deserialization. The service is expecting properly formed JSON.

Update your API to return a valid JSON object by using "application/json" and returning an object as shown in the following post: Spring MVC - How to return simple String as JSON in Rest Controller

ShellNinja
  • 629
  • 8
  • 25
0

You need to place the console.log inside the .subscribe() method

 this.myService.getData().subscribe(data => {
     this.data = data;
     console.log(this.data);
});
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
0

You have to set responseType to 'text' in a request options object. Here's a sample:

return this.http.get(`myApi/ExampleMethod/param`, { responseType: 'text' })
                .pipe(
                    catchError(
                        this.errorHandler.handleError.bind(this)
                    )
                 );
kgzdev
  • 2,770
  • 2
  • 18
  • 35
Paweł
  • 21
  • 5