0

I have a RestApi which sends me the response in a Json Format which has for example a address object which then holds the address1, address2, city etc. So i created an interface in my app which holds the definition of these objects like

export interface ISurveyResponseDetail {
  docID?: string;
  permission?: string;
  property?: IProperty;
  surveyID?: string;
}
export interface IProperty {
  address1?: string;
  address2?: string;
  city?: string;
  state?: string;
  zip?: string;

then in my ts file i want to use a data adapter to map my response into this interface. But i am not sure how i would the property Object of type IProperty and then be able to assign the values

static adaptSurveyResponseDetail(data): ISurveyResponseDetail {
        if (data) {
            return {
                property:
                // address1 _.get(data, 'property.address1', null),
                // city _.get(data, 'property.city', null),
                docID: _.get(data, 'docID', null),
                permission: _.get(data, 'permission', null),
                surveyID: _.get(data, 'survey_id', null),
              };
            } else {
            return data;
        }

    }
0

3 Answers 3

1

Try something like this

static adaptSurveyResponseDetail(data): ISurveyResponseDetail {
    if (data) {
      return {
        property: {
          address1: data.address1,
          address2: data.address2,
          city: data.city,
          state: data.state,
          zip: data.zip,
        },
        docID: data.docID,
        permission: data.permission,
        surveyID: data['survey_id'],
      };
    } else {
      return data;
    }
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Thats not the issue i am having. Whats my problem is that my Interface ISurveyResponseDetail has an property object of type IProperty which in turn has then the address1 etc. I am having an issue assigning values to address1 as it does not directly exist in the ISurveyResponseDetail
1

I have a RestApi which sends me the response in a Json Format

I think maybe you are making this more complex than it needs to be? HttpClient has generic methods that allow you to cast the parsed json response to an interface.

getSurveyResponse() : Observable<ISurveyResponseDetail> {
  return httpClient.get<ISurveyResponseDetail>('/end/point/here');
}

4 Comments

In my Case the API returns additional info depending on the Endpoint. Which means it first would be a API Response and then in the Data Part it would be depending on the endpoint a <ISurveyResponseDetail> or <ISurveyResponseDetail[]>
@NoSoup4you - Ideally you should be writing at least 1 service call per end point which means that my above example would be extended with an additional method like getSurveyResponses(): Observable<ISurveyResponseDetail[] { .... (notice the plural form in the method name).
I get the general idea but how would i do that when the type i could observer is the APIResponse and then lets say i would want the ISurveyResponseDetail which will be in the Data element of the API response
@NoSoup4you - either httpClient.get<{data: ISurveyResponseDetail}>('end/point') or you can use pipe with map to return the data property directly: httpClient.get<{data: ISurveyResponseDetail}>('end/point').pipe(map((result) => result.data))
1

Don't make all of the properties of your interface optional. You can define an extra type to be partial, and only use that in cases where the flexibility is needed.

export interface ISurveyResponseDetail {
  property: IProperty;
  docID: string;
  permission: string;
  property: IProperty;
  surveyID: string;
}

export type ISurveyResponseDetailPartial = Partial<ISurveyResponseDetail>;

export interface IProperty {
  address1: string;
  address2: string;
  city: string;
  state: string;
  zip: string;
}

export type IPropertyPartial = Partial<IProperty >;

Don't use underscore to set default values as null. Define a default object instead.

const DEFAULT_SURVEY_RESPONSE_DETAIL: ISurveyResponseDetail = {
  property: DEFAULT_PROPERTY,
  docID: null,
  permission: null,
  property: null,
  surveyID: null
}

const DEFAULT_PROPERTY: IProperty{
  address1: null,
  address2: null,
  city: null,
  state: null,
  zip: null
}

You don't need an adapter to rebuild the object, because the HTTP client can deserialize JSON into a type for you. If you want to have missing properties set as null, then constructor a new object using the default object as the first parameter and then apply the values. Any missing properties will remain set as null.

getSurveyResponseDetail() : Observable<ISurveyResponseDetail> {
  return this.http.get<ISurveyResponseDetail>(...).pipe(
     map(data => {
        const property = {...DEFAULT_PROPERTY, ...(data.property || {})};
        return {...DEFAULT_SURVEY_RESPONSE_DETAIL, ...data, property};
     });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.