I would like to know if this is the best/most efficient/industry standard way of converting from the http
response to an array of typed values:
Type class:
export class University {
public "state-province": string;
public country: string;
public name: string;
constructor(state_province: string, country: string, name: string) {
this["state-province"] = state_province;
this.country = country;
this.name = name;
}
}
Here is the http
request and conversion. The code in question is within the map(...)
call:
const resp = this.http
.get<University[]>(`http://universities.hipolabs.com/search?country=United+Kingdom&name=camb`)
.pipe(map(respData => {
const uniArr: University[] = [];
respData.forEach(element => {
uniArr.push(new University(element['state-province'], element.country, element.name));
});
return uniArr;
}))
.subscribe(respData => {
console.log('Content:', respData);
});
In C#
there are many easier ways to convert the response data of the get
request into an array (or list) of typed instances. Am I doing this correctly here, in Angular/RxJS?
1 Answer 1
Addressing Your Main Question
I would like to know if this is the best/most efficient/industry standard way of converting from the http response to an array of typed values
Just as an array has its forEach()
method it also has a map()
method. That method essentially pushes the return value of the callback function into an array and returns the array. Because of this the code within the map
function callback can be simplified using that method instead of calling the forEach()
method.
Thus this inner block:
.pipe(map(respData => { const uniArr: University[] = []; respData.forEach(element => { uniArr.push(new University(element['state-province'], element.country, element.name)); }); return uniArr; })
can be simplified to:
.pipe(map(respData => {
return respData.map(element => {
return new University(element['state-province'], element.country, element.name);
});
})
Notice there is no need to declare the array- i.e. uniArr
because the map
method returns an array.
And that can be simplified because there is only a single statement being returned
.pipe(map(respData => {
return respData.map(
element => new University(element['state-province'], element.country, element.name)
);
})
And the return
before the call to the map
method could also be removed though it might make for a long line that some would split
.pipe(map(respData => respData.map(element => new University(
element['state-province'],
element.country,
element.name
))))
Using the map
method approach there are no side-effects of the callback function and thus it is a pure function. This means it is simpler to test, and allows for fewer indentation levels.
Review
While there isn't much code to review here, the present code appears quite readable. Indentation is consistent and variables have acceptable names.
It would be wise to check respData
to ensure it is an array before calling a method like forEach()
or map()
on it, and if the code doesn't already catch exceptions from the call to this.http.get()
then it would be wise to also handle those cases. For example, what happens if the network fails or the API is not available?
-
\$\begingroup\$ Condensed to the max! I like it \$\endgroup\$Marcello di Simone– Marcello di Simone2022年05月25日 06:38:35 +00:00Commented May 25, 2022 at 6:38
Explore related questions
See similar questions with these tags.