2

I have this interface

export interface Student {
    cf: string,
    firstName: string,
    lastName: string,
    dateOfBirth: Date,
    description?: string,
    enrollmentDate?: Date
}

I want to populate an array of students with a http get request, which returns the following json for each student

{cf: "blablabla", first_name: "Mario", last_name: "Rossi", date_of_birth: "1998-01-24", enrollment_date: "2019-03-20" },

As you can see, the interface has different names from the response (firstName instead of first_name), so when I print to the console the names of the students I get undefined.

This is the service function from which I get the data

  getStudents(): Observable<Student[]> {
    return this.httpClient.get<Student[]>(this.studentsUrl, this.baseService.httpOptions);
  }

And here is my students component

export class StudentsComponent implements OnInit {

  students: Student[];
  childIcon = faChild;
  plusIcon = faPlus;
  private _newStudent: boolean = false;

  constructor(private studentsService: StudentsService) { }

  ngOnInit(): void {
    this.studentsService.getStudents().subscribe(
      (result: Student[]) => {
        this.students = result;
        this.students.forEach(student => console.log(student));
      },
      error => console.log(error)
    )
  }
}

Is there a way to convert the json response to my Student interface? Several answers on stack overflow suggest map is the way, but I don't understand how to use that operator alog with subscribe

1 Answer 1

2

One way would be manually loop through the array and define new keys and delete obsolete ones before returning the array using RxJS map.

Service

import { pipe } from 'rxjs';
import { map } from 'rxjs/operators';

getStudents(): Observable<Student[]> {
  return this.httpClient.get<Student[]>(this.studentsUrl, this.baseService.httpOptions).pipe(
    map(response => response.forEach(student => {
        student.firstName = student.first_name;
        student.lastName = student.last_name;
        student.dateOfBirth = student.date_of_birth;
        student.enrollmentDate = student.enrollment_date;
        delete student.first_name;
        delete student.last_name;
        delete student.date_of_birth;
        delete student.enrollment_date;
      });
    )
  );
}

But depending on the number of elements in the array, this could be a heavily taxing operation for a single HTTP request. Couldn't you define the interface definition to match the one of the API?

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting solution, although I don't understand the need for deleting the keys. Anyway yes, surely I can match the interface to the one on the API, and I think I'm going for this way. My question was because I'm new to Angular and I want to consider every possible solution
Without deletion both the forms of keys will persist. For eg., both firstName and first_name. There is no built-in way of renaming object keys in Javascript.

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.