Home > Back-end >  flattening nested objects typescript
flattening nested objects typescript

Time:11-06

I am looking to flatten a nested object in my controller (new to Loopback and Typescript)

Here is my model :

export class SampleModel {
  id: number;
  code: number;
  guide?: string;
  gradeData?: string;
}

Here is an example object :

{
  "id": 1,
  "code": 12345,
  "guide": "Guide for 2021",
  "gradeData": {
    "en": "Eng grade",
    "de": "Ger grade"
  }
}

Here is my controller:

// returns an array of SampleModel objects
@get('/guides')
async find(
@param.query.string('lang') lang: string,
@param.filter(SampleModel) filter?: Filter<SampleModel>
): Promise<SampleModel[]> {
return this.sampleModelRepository.find(filter); //this returns Promise<SampleModel[]>
}

I want to tweak this response a little based on lang. For ex: if lang = en I want the response to look like

[
  {
    "id": 1,
    "code": 12345,
    "guide": "Guide for 2021",
    "gradeData": "Eng grade"
  }
]

CodePudding user response:

Something like this? Ofcource you need to make the langcode dynamic

[{
  "id": 1,
  "code": 12345,
  "guide": "Guide for 2021",
  "gradeData": {
    "en": "Eng grade",
    "de": "Ger grade"
  }
}].map(e=>{
    e.gradeData = e.gradeData["en"];
    return e;
})

Returned object:

[
    {
        "id": 1,
        "code": 12345,
        "guide": "Guide for 2021",
        "gradeData": "Eng grade"
    }
]

CodePudding user response:

Thanks to @Firewizz I was able to do this. Here is my updated controller :

  // returns an array of SampleModel objects
  @get("/guides")
  async find(
    @param.query.string("lang") lang: string,
    @param.filter(SampleModel) filter?: Filter<SampleModel>
  ): Promise<SampleModel[]> {
    const res = this.sampleModelRepository.find(filter); //this returns Promise<SampleModel[]>
    if (lang != null) {
      (await res).map((e) => {
        if (e.gradeData != null && e.gradeData.hasOwnProperty(lang)) {
          e.gradeData = new Map(Object.entries(e.gradeData)).get(locale);
          // not sure why this is required but when I tried
          // `e.gradeData = e.gradeData[locale];`
          // I get compilation error " Element implicity has an 'any' type because index expression is not of type 'number' " maybe because gradeData is defined as a String but when I do
          // console.log(typeof e.gradeData)
          // I get object

          // I also tried
          // `e.gradeData = JSON.parse(e.gradeData)[locale];`
          // I get " SyntaxError: Unexpected token o in JSON at position 1 " and that could be because it's already an object

          // I then tried
          // `e.gradeData = JSON.parse(JSON.stringify(e.gradeData))[locale];`
          // this also works but I think converting this to a map as a workaround is better
        }
        return e;
      });
    }

    return res;
  }
  • Related