cerialize icon indicating copy to clipboard operation
cerialize copied to clipboard

Having some difficulties in deserializing an Array of a custom type

Open Marcos-Amazonas opened this issue 5 years ago • 0 comments

I'm developing a social netwrok aplication comprised of a Rails based API and a Angular7 web application. Basically the Angular aplication is a web interface to the API.

I'm using the cerialize Typescript library to map the return of the rails API to my Angular models, the goal is to map the json response from snake_case to camelCase.

Basically I'm able to deserialise one object, but I can't deserialize an array of objects.

Specifically in my case I'm trying to log in in the application and than make a request to get all of the logged user friendships, because of that I've modeled a class named CurrentUser wich corresponds to the login response and Friendship wich corresponds to the friendship response.

Here's one of the API's responses and how I'm mapping it to one of my models with the library, specifically this model maps the response of the login process:

The response:

loginResponse: {
   created_at: "2019-05-25T09:18:55.708-03:00"
   email: "[email protected]"
   enabled: true
   expire_at: "2019-05-29T14:45:51.000-03:00"
   id: 2
   login: "Diego"
   name: "Diego"
   profile_id: 2
   token: "65zWGEea6M9DCn2PsL-z"

   user_image: {
      enabled: true
      id: 2
      public_image_path: "http://localhost:3000/images/users`
   }
}

The TS mode class:

export class CurrentUser {
  // * ============================================
  // * Attributes
  // * ============================================
  @autoserialize id: number;
  @autoserialize name: string;
  @autoserialize email: string;
  @autoserialize  login: string;
  @autoserialize enabled: boolean;
  @autoserializeAs('profile_id') profileId: number;
  @autoserializeAs('created_at') createdAt: Date;
 
  @autoserialize token: string;
  @autoserializeAs('expire_at') expireAt: Date;

  @deserializeAs(UserImage, 'user_image')  userImage: UserImage;

  // * ============================================
  // * Methodds
  // * ============================================
  constructor() { }
}

The TS service class that performs the request:

export class LoginService {
  // * ============================================
  // * Attributes
  // * ============================================
  private resourceLogin = 
  'http://localhost:3000/api/v1/logins';
  
  private resourceAuthToken = 
  'http://localhost:3000/api/v1/core_module/permission_module/authtokens';

  // * ============================================
  // * Methodds
  // * ============================================
  constructor(
    private http: HttpClient,
    private router: Router,
    private friendshipService: FriendshipService
  ) {}

  **THIS IS THE METHOD THAT PERFORMS THE REQUEST**
  public doLogin(login: Login): Observable<CurrentUser> {
    let httpParams = new HttpParams();
    httpParams = httpParams.set('login[email]', login.email.toString());
    httpParams = httpParams.set('login[password]', login.password.toString());

    return this.http
      .post<Login>(this.resourceLogin, httpParams)
      .pipe(map((data) => Deserialize(data, CurrentUser)));
  }
}

This process work perfectly, it transforms all of the annotated properties. The problem emerges when I try to map the response of the method that request all of the logged user friendships, I've tried 2 ways of writing the code.

Heres the method that performs the friendships request to the api:

// FIRST VERSION
public findUserFriendships(currentUser: CurrentUser): Observable<Friendship[]> {
    let httpParams = new HttpParams();
    httpParams = httpParams.set('user_friendships', 'true');
    httpParams = httpParams.set('user_id', currentUser.id.toString());

    return this.http
      .get<Friendship[]>(this.resourceFriendship, {params: httpParams})
      .pipe(map((data) => Deserialize(data, Friendship)));
  }


// SECOND VERSION
public findUserFriendships(currentUser: CurrentUser): Observable<Friendship[]> {
    let httpParams = new HttpParams();
    httpParams = httpParams.set('user_friendships', 'true');
    httpParams = httpParams.set('user_id', currentUser.id.toString());

    return this.http
      .get<Friendship[]>(this.resourceFriendship, {params: httpParams})
      .pipe(map((data) => data.map((item) => Deserialize(item, Friendship))));
  }

I'm debugging the the application with the debugger term, so I basically write debbuger in my code and when the code reaches that point the application stops.

Through this debug method I was able to find out that when I use the First version of the findUserFriendships method I get an Friendship empty object, and when I user the Seccond version of the findUserFriendships I get nothing, I doesn't even stop at the debugger;

Anyways the end goal is to map all of the Friendship objects in the Friendships array.

Thanks in advance.

Marcos-Amazonas avatar May 29 '19 20:05 Marcos-Amazonas