0

I'm new to angular came from angularjs, and I'm confused about rxjs observable.

Example:

User.ts

export class User {
id?:any;
username:string;
password:string;
}

With <User[]>

myUser(header: any) {
const url = `${this.mainUrl}/my_user`;
return this.http.get<User[]>(url, header).pipe(
  map(resp => {
    return resp;
  })
);
}

Without <User[]>

myUser(header: any) {
const url = `${this.mainUrl}/my_user`;
return this.http.get(url, header).pipe(
  map(resp => {
    return resp;
  })
);
}

This will return the same result. So I'm confused on whats the difference, with or without it.

EDIT:

This is the data I'm fetching nowhere near look like my User.ts but its not throwing an error.

{
"username": "mhqadmin",
"inserted_at": "2019-02-06T07:01:17.024874",
"id": "b491e7c3-da11-40fe-b4b7-8f97fa88a9fd",
"avatar": {
    "middlename": "mhqadmin",
    "lastname": "headquarters",
    "id": "939c2eec-573e-4245-adcc-0771c73f22e4",
    "firstname": "marte"
},
"app_role": "mhq-admin",
"app_permission": true
}
2
  • This is common javascript trick. If you don't indicate type, typescript assing <any> type to varibales. So it's normal to see same result because typeless varibales are taking form by itself. Commented Mar 6, 2019 at 6:02
  • @shadowman_93 so its safe to say I can code without putting it <User[]> ? Commented Mar 6, 2019 at 6:03

2 Answers 2

2

The difference between this.http.get<User[]> and this.http.get is that you're passing a type into the generic signature of get.

From the Angular source code:

  get<T>(url: string, options?: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe?: 'body',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
  }): Observable<T>;

The get<T> stands for a generic type signature, it means that you can declare what the data should look like. When you declare this.http.get<User[]>, you're saying that the data that comes back should look like an array of User - but that is all a TypeScript based idea, it's unrelated to RxJS/Observables/JavaScript. When you call this.http.get, you're still just using a JavaScript runtime, it's just making an HTTP request for data. Passing an interface into a generic signature does not force the actual data coming back to change - but it enhances your type safety by enabling the TS compiler to understand what the data should look like.

EDIT: It appears that you want to pick pieces of data off to match your User.ts class. By providing a type, like this: this.http.get<User[]>, that will not change the data, it will only hint to the code editor what the data should look like, but it doesn't touch the data at all. You'll need to actually pluck the data out if you want to change the shape of it to match your User.ts class, something like this:

myUser(header: any) {
  const url = `${this.mainUrl}/my_user`;
  return this.http.get(url, header).pipe(
    map(resp => {
      return {
        id: resp.id,
        username: resp.username
      };
    })
  );
}

That would help you match to an interface/class that looks like this:

interface User {
  id: string;
  username: string;
}

But that is not the shape of the data, or the type of your data that you are getting, that looks more like this:

interface User {
  username: string;
  inserted_at: string;
  id: string;
  avatar: Avatar;
  app_role: Role;
  app_permission: boolean;
}

That is a type that better matches what is actually coming back from your backend. With whatever type you pass into the generic, that will be the model for what is coming out of the Observable, but you'll need to then match the actual interface correctly, as I've done in the map example.

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

2 Comments

But the data that I'm getting is nowhere like my User.ts, Can you check my edit, Sorry for my bad english if it doesnt make sense
@Priz I added some more information, hope it helps!
2

With <User[]> you instruct Typescript that the return of http.get is an Observable<User[]> so it will infer the type of myUser to Observable<User[]>. This is very helpful further in your application since the tooling will know what properties exist on your reponse types and if you did a mistake/typo. It will also fail during compile time if you access properties that don't exist. That is because http.get is a generic method where you can specify the response type (but if you don't specify it, it uses any).

Without <User[]>, typescript will just use the any type, which brings no additional benefit over plain javascript.

Also map(resp => { return resp; }) is useless and you can safely remove it.

1 Comment

Thanks for pointing out the map didnt see it, But the data getting fetched is not even close to my User.ts. I will update on what data its getting.

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.