Home > Software design >  Angular doesn't create an object out of JSON response
Angular doesn't create an object out of JSON response

Time:11-13

I'm trying to create an object out of my json (from a http request) but it's a plain string.

Interfaces:

export interface CeleryTask {
  uuid: string,
  state: string,
  received: string,
  result: Chat,
}

export interface Chat {
  id: number;
  chatTitle: string;
  chatId: string;
  users: User[];
  archived: boolean,
}

GET Request in my service:

loadAllSuccessTasksFromFlower(): Observable<CeleryTask[]> {
    return this.http.get<CeleryTask[]>("http://localhost:5566/api/tasks?state=SUCCESS")
      .pipe(map(response => Object.entries(response)
        .map(entry => ({
          uuid: entry[0],
          state: entry[1].state,
          received: entry[1].received,
          result: entry[1].result
        }))))
  }

HTTP Response:

{
   "67fe1783-4451-4fa5-838e-b78279fd5c07":{
      "uuid":"67fe1783-4451-4fa5-838e-b78279fd5c07",
      "name":"upload.tasks.importWorkTask",
      "state":"SUCCESS",
      "received":1668285215.4455156,
      "sent":null,
      "started":1668285219.4739492,
      "rejected":null,
      "succeeded":1668285419.1474545,
      "failed":null,
      "retried":null,
      "revoked":null,
      "args":"('C:\\Users\\xx\\AppData\\Local\\Temp\\xxx', 'xx.pdf')",
      "kwargs":"{}",
      "eta":null,
      "expires":null,
      "retries":0,
      "result":"{'id': 9, 'chatTitle': 'My Chat'}",
      "exception":null,
      "timestamp":1668285419.1474545,
      "runtime":199.67199999999866,
      "traceback":null,
      "exchange":null,
      "routing_key":null,
      "clock":599,
      "client":null,
      "root":"67fe1783-4451-4fa5-838e-b78279fd5c07",
      "root_id":"67fe1783-4451-4fa5-838e-b78279fd5c07",
      "parent":null,
      "parent_id":null,
      "children":[
         
      ],
      "worker":"celery@xxx"
   }

When I console.log the result:

{
  "uuid": "67fe1783-4451-4fa5-838e-b78279fd5c07",
  "state": "SUCCESS",
  "received": 1668285215.4455156,
  "result": "{'id': 9, 'chatTitle': 'My Chat'}"
}

The id & chatTitle is not a chat object, it's an plain string. So it's not possible to access object.result.chatTitle

Any idea how to solve this problem?

CodePudding user response:

One way to get the object from the received string would be

result: JSON.parse(entry[1].result);

Build a type guard to let typescript understand that you really have a Chat object

function isChat(o: any): o is Chat {
  // check whatever is necessary to be a Chat object
  return "id" in o && "chatTitle" in o
}

Use the typeguard like this

const parsed = JSON.parse(jsonString);
if (isChat(parsed)) {
  // do something with now correctly typed object
} else { 
  // error handling; invalid JSON format 
}

See https://stackoverflow.com/a/62438143/7869582 for more info on that

  • Related