Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse Date object properly of TypeScript class when HttpClient mapping won't?

Task.ts:

export class Task {
    name: string;
    dueDate: Date;
}

tasks.service.ts:

@Injectable()
export class TasksService {

    constructor(private http: HttpClient) { }

    getTasks(): Observable<Task[]> {
        return this.http.get<Task[]>(`${WEBAPI_URL}/Tasks`);
    }
}

The Task objects I get back from getTasks() have their dueDate field assigned but the value is of type string instead of Date like I would expect.

Some searching lead me to this issue on the Angular github which made clear to me that HttpClient has no intent of properly parsing my object. Unfortunately the issue didn't give helpful guidance about what I should actually be doing to get my Date object. What do I do?

like image 373
Kyle V. Avatar asked Oct 29 '25 01:10

Kyle V.


1 Answers

You have several options here.

1) You can deal with the date as a string in the UI. So change the definition of Task to retain the date as a string and work with it that way, converting it to a date for calculations as needed.

2) You can map each object coming back from the Http request to a Task object. Something like this:

getTasks(): Observable<Task[]> {
    return this.http.get<Task[]>(`${WEBAPI_URL}/Tasks`)
        .pipe(
            map(items => {
                const tasks: Task[] = [];
                return items.map(
                    item => {
                        item.dueDate = new Date(item.dueDate);
                        return Object.assign(new Task(), item);
                    });
            }),
            tap(data => console.log(JSON.stringify(data))),
            catchError(this.handleError)
        );
}

This also have the benefit of having actual task objects in your array, meaning that if you ever add Task methods or getters/setters they will be correctly associated with your tasks array.

EDIT: It may be better to build a utility class that handled the serialization/deserialization of your objects. Then the above code would look more like this:

getTasks(): Observable<Task[]> {
    return this.http.get<Task[]>(this.url)
        .pipe(
            map(TaskSerializer.serialize),
            catchError(this.handleError)
        );
}
like image 120
DeborahK Avatar answered Oct 30 '25 19:10

DeborahK