Manu Chadha
Manu Chadha

Reputation: 16755

unable to correctly map json to data model

I want to model the following information into json but am unable to do so.

The server sends result of an operation to the client using the following model

class Result (result:string, additional-info:string)

additional-info could contain a json or a string depending on the use case. Thus its type is String. When I need to send a json in it, I simply send a string with a valid json syntax and I suppose the the Angular client would be able to convert the string into a json using JSON.parse.

The json I want to send to the client looks like

{
    "result": "success",
    "additional-info": {
        "list ": [{
            "tag": "sometag",
            "description": "some description"
        }]
    }
}

I checked on jsonlint (https://jsonlint.com/) that the structure is correct.

On the client side (Angular), I am handing the message as follows:

  getQuestions(some args){
      console.log('response from server:',res)
      console.log('response body',res.body)
      let jsonResponse:ServerResponseAPI = res.body //should contain result and additional info
      console.log("result: "+jsonResponse.result+", additional info:"+jsonResponse.additionalInformation)
      let jsonList:string = jsonResponse.additionalInformation
      console.log("jsonQuestionList: "+jsonList)
      let information:Information = JSON.parse(jsonList)
      console.log("information:"+information)
    });
  }

ServerResponseAPI is defined as

export class ServerResponseAPI{ 
  constructor ( public result:string,
               public additionalInformation:string){}
}

When I execute the code, I see the following prints on browser's console but I see that error that additional-info is not define.

response body {result: "success", additional-info: "{"list ": [{"tag": "sometag", "description": "some description"}]}"} list-management.service.ts:46 result: success, additional info:undefined

I can see that the body contains result and additional-info but after casting the body to ServerResponseAPI, I see that result is success but additional-info is undefined.

Upvotes: 1

Views: 51

Answers (1)

Manu Chadha
Manu Chadha

Reputation: 16755

in res.body, javascript creates an object

{
    "result": "success",
    "additional-info": {
        "list ": [{
            "tag": "sometag",
            "description": "some description"
        }]
    }
}

The object has two keys - result and additional-info. Lets call it Object1

I assign it to an object which has keys result and additionalInfo. Note the difference in naming convention in additionalInfo. In javascript, names of variables are case sensitive, so the above two are different. Lets call this object2

Now result from object1 gets assigned to result from object2 because the keys match (same name result) additional-info becomes a new key in the object2 additionalInfo key of object2 stays undefined as no key from object1 maps to additionalInfo

To solve the issue, I had to create a additional-info key ServerResponseAPI (alternatively I could have also changed my JSON property name to additionalInfo but I didn't want to change that). This is done in Angular as

export class ServerResponseAPI{
  'additional-info':string;
  constructor ( public result:string,
               public additionalInformation:string){
    this['additional-info'] = additionalInformation;
  }
}

In my code, I now access the keys as

let jsonResponse:ServerResponseAPI = res.body //contains result and additional info
      console.log("result: "+jsonResponse.result+", additional info:"+jsonResponse['additional-info'])
      let jsonQuestionList:string = jsonResponse['additional-info']

Upvotes: 1

Related Questions