0

I have 2 Interfaces:

DTO.ts

export interface Report{
berichtId: number,
summary: Label
}

export interface Label{
text: string
}

I use them to type my HttpClient get request, to receive an array of Reports:

Dao.service.ts

getReports():Observable<DTO.Report[]>{
  return this.http.get<DTO.Report[]>(Dao.API+'report/current')
  .pipe(
    retry(3),
    catchError(this.handleErrors)
  );

What I get is this JSON:

[
{
"berichtId":1777,
"summary":
"{\"text\":\"asdf\"}"
}
]

Now I want to read them out but these slashes dont let me convert the JSON to my pre defined interface Report object. It just translates it to a normal string.

this.dao.getReports().subscribe(report=>{
   console.log(report[0].summary); // {"text":"asdf"}
   console.log(report[0].summary.text) // undefined
});

What is the best way to handle that problem? There are solutions online but they are often rather counter intuitive. There must be a better way in Angular.

  • Why are you using a string to represent an object? – Edric Dec 13 '19 at 12:16
  • Does this answer your question? [Safely turning a JSON string into an object](https://stackoverflow.com/questions/45015/safely-turning-a-json-string-into-an-object) – Edric Dec 13 '19 at 12:18
  • Are you sure this is the actual JSON you receive? If I use a simple jQuery `$.getJSON()` with your structure I get a parse error because of the `\`. – John Archer Dec 13 '19 at 12:31
  • @Edric What do you mean? I want to get the attribute "summary" as an object with its own attribute "text" in it. – TheAmygdala Dec 13 '19 at 12:45
  • @Edric Thanks but your suggestion doesnt help me. This problem needs a little more than JSON.parse(report). I am working with interfaces and I want to solve the problem in the dao.components, where I use the http.get method. That way I need to implement it just once, so it always gives back a correct report object. Angular already converts the incoming json but it is not able to read the content of "summary". That is my problem – TheAmygdala Dec 13 '19 at 12:51
  • @JohnArcher I edited the JSON. Now it is correct. – TheAmygdala Dec 13 '19 at 12:56
  • @TheAmygdala Alright, now this makes more sense. So, basically @Edric is right. But you have to write `JSON.parse(report[0].summary)` not `JSON.parse(report)`. – John Archer Dec 13 '19 at 13:02
  • @JohnArcher even though, the compiler complains because summary is an object and not a string. Thats because of the implemented interface of "Label" which the compiler acknowledges as an object. That way `JSON.parse(report[0].summary)` leads to an error because this method only takes strings. – TheAmygdala Dec 13 '19 at 13:08
  • I see. See my comment on the answer. So try to cast summery to string. – John Archer Dec 13 '19 at 13:09

2 Answers2

1

I think you need to use map operator from rxjs/operators before returniing data from service.

I have intercepted the data using map (rxjs) and then parsed the summary.

Demo (check console on button click)

Service

import { Injectable } from '@angular/core';
import { of, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Report } from './types';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class DataService {

  constructor(private http: HttpClient) { }

  getReports(): Observable<Report[]> {

    return this.http.get<any[]>('api')
      .pipe(
        map(
          values =>
            values.map(val => {
              val.summary = JSON.parse(val.summary)
              return val;
             }
            )
        ));
  }

  // mock methos for demo
  mockGetReports() {
    return of<any[]>([
      {
      "berichtId":1777,
      "summary":
      "{\"text\":\"asdf\"}"
      }
      ])
      .pipe(
        map(
          values =>
            values.map(val => {
              val.summary = JSON.parse(val.summary)
              return val;
             }
            )
        ));
  }

}
Plochie
  • 3,944
  • 1
  • 17
  • 33
-1

I think you should try JSON.parse() or if it does not help then you can try this npm library

I hope this solves your issue.

Chirag Chaudhari
  • 1,617
  • 3
  • 14
  • 20
  • Thanks but your suggestion doesnt help me. This problem needs a little more than JSON.parse(report). Angular already converts the incoming json but it is not able to read the content of "summary". That is my problem. And I dont know how I can map the "summary" attribute, so it acknowledges the incoming content as JSON. Even if I make `report[0].summary = JSON.parse(report[0].summary)` the problem will be, that the compiler will complain because "summary" is an object (because of the given interface) and JSON.parse() only takes strings – TheAmygdala Dec 13 '19 at 13:05
  • Does `report[0].summary = JSON.parse(report[0].summary)` or similar cast syntax work? – John Archer Dec 13 '19 at 13:09