Funn_Bobby
Funn_Bobby

Reputation: 715

Populate Typescript Class with JObject

I'm moving from AngularJS to Angular 6, in JS I used $resource and when I got data back that looked like this...

{
  "SomeList": [{
      "SomeID": "123456",
      "SomeName": "Joe Shmoe",
      "SomeCode": "987654",
      "Address1": null,
      "Address2": null,
      "City": null,
      "State": null,
      "Zip": null,
      "Phone1": null,
      "Phone2": null,
      "Email": null

    },
    {
      "SomeID": "234567",
      "SomeName": "Joe Bagodonuts",
      "SomeCode": "456123",
      "Address1": null,
      "Address2": null,
      "City": null,
      "State": null,
      "Zip": null,
      "Phone1": null,
      "Phone2": null,
      "Email": null
    },
    etc...
  ]
}

It just flowed into a variable very nicely and I could use the data.

In Typescript I have set up...

A Model

export class SomeList {
  SomeID: string;
  SomeName: string;
  SomeCode: string;
  Address1: string;
  Address2: string;
  City: string;
  State: string;
  Zip: string;
  Phone1: string;
  Phone2: string;
  Email: string;
}

export class SimpleResponse < T > {
  Data: T;
}

export class SimpleResponseLower < T > {
  data: T;
}

A variable set to the model in a singleton

public static somies: SomeList[];

A Data Service

getSomeList<SomeList>(year: number): Observable<SomeList[]>{
  const url = `${Urls.Somies()}?cropYear=` + year;
  var host = window.location;
  var combineurl = host.href + 'api/RequestHandler?uri=' + url;
  return this.http.get<SimpleResponse<SomeList[]>>(combineurl).pipe(map(r => 
r.Data));

 ***The call below is what returned the sample data above
 //return this.http.get(combineurl).pipe(map(value =>{return value}));

  }
}

and A call to the data service filling the class

this.dataService.getSomeList < SomeList > (2018)
  .subscribe((data) => {
      this._formValues.somies = data;
    },
    () => {
      // put some code here and remove console.log
    }); // end of error block);
}

I've tried just about every configuration I can think of and data is coming back "undefined" with no errors and the link listed in the Network tab of the browser populating.

Any help or ideas are greatly appreciated!!

Upvotes: 1

Views: 389

Answers (2)

Funn_Bobby
Funn_Bobby

Reputation: 715

Okay, I was able to figure this out. What I had to do was...

Change the type being returned from api from

string jsonString = client.DownloadString(fullUri);                                
JObject infoObj = JsonConvert.DeserializeObject<dynamic>(jsonString);
string data = infoObj.ToString();                                   
return data;

To

string jsonString = client.DownloadString(fullUri);                                
JObject infoObj = JsonConvert.DeserializeObject<dynamic>(jsonString);
SimpleResponse<JObject> data = new 
SimpleResponse<JObject>();
data.Data = infoObj;                                
return data;

and on the typeScript side I had to change the model to

export class SimpleResponse<data> {
data: data;
}
export class SomeResponse{
SomeList: SomeList[];
Message: string;
}

and in my data service instead of returning...

<SimpleResponse<SomeList[]>>

I return

<SimpleResponse<SomeResponse>>

I'm not sure if this is the "TypeScript" way of doing it or if there is a better more generic way so I don't have to add a ResposeClass for each call I make to the API...but it is working!!

Upvotes: 0

Wingnod
Wingnod

Reputation: 626

Your JSON should map directly to your models.

Either your data should be:

'{
   "Data": [
      {
        "SomeID": "123456",
        "SomeName": "Joe Shmoe",
        "SomeCode": "987654",
        "Address1": null,
        "Address2": null,
        "City": null,
        "State": null,
        "Zip": null,
        "Phone1": null,
        "Phone2": null,
        "Email": null
      }, etc...
   ]
}

Or your simple response should expect SomeList:

export class SimpleResponse<T> {
   SomeList: T;
}

And you should map to the SomeList property on the response instead of Data.

return this.http.get<SimpleResponse<SomeList[]>>(combineurl).pipe(map(r 
 => r.SomeList));

Upvotes: 1

Related Questions