1

I have a bunch of entities I've declared:

export class Meeting implements IHasId {
    id = 0;
    locationId = 0;
    meetTime = new Date();
    isFinalized = false;
    imageId: number = null;
    description = '';
    name = '';
}

I have a generic crud service which handles resolving these to its original type

export class ApiResourceBaseService<T extends IHasId> {
  get(id: number): Observable<T> {
    return this.http.get<T>(`${this.apiUrl}/${this.route}/${id}`);
  }
}

Typescript Generics are only superficial, so when I call get<T> typescript assumes my json is correct. However, My date objects are not resolved properly, they are resolved as string.

I have several entities, It would be annoying to create custom constructors/adapters to parse the dates.

does anyone have a better idea for automatically resolve dates?

5
  • simple answer no. JSON by definition only holds primitive types (string, boolean and number) and nested arrays and more objects since date is not a primitive type to exchange between client and server you need to trim it down to a recognizable primitive format in this case a string Commented Oct 10, 2019 at 23:31
  • @joyBlanks yeah i get that but I'm debating on trying two different ways, Create an interceptor which attempts to parse the the fields as dates, or maybe using hook into the typescript compiler to automatically create adapters. I'm just trying to see if anyone has already solved this issue Commented Oct 10, 2019 at 23:55
  • ok got it. yup somebody must have written an interceptor for sure, but scanning through all strings in depth and you knowing most of the anticipated JSON for your app I think you can hook something up. good luck :) Commented Oct 10, 2019 at 23:57
  • 1
    Thanks, I mostly just hate to have to write and adapter for each entity I'd rather take the time once. I'm just hoping someone thought of an east savvy way to do this. If not I'll post an answer in a few days Commented Oct 11, 2019 at 0:52
  • @joyBlanks I ended up just hacking together a date transformer in the interceptor, but i think in the future I'll just autogenerate my models from the api documentation Commented Oct 11, 2019 at 23:03

1 Answer 1

2

I've created an interceptor to transform the data, In the future I'll probably just have auto generate my models and api resources from the api documentation and avoid this but for now I'm just using this hack:

export class ModelBinderInterceptor implements HttpInterceptor {

    // regex of ISO 8601 Date.
    DATE_TIME_TIMEZONE_REGEXP =
    /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;

    constructor() {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        return next.handle(req).pipe(tap((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                event = event.clone({body: this.modifyBody(event.body)});
            }
            return event;
        }));

    }

    private modifyBody(body: any) {
        return this.deserializeDates(body);
    }

    private deserializeDates(obj) {
        if ((!(obj instanceof Object)) || (isString(obj))) {
            return obj;
        }

        for (const key of Object.keys(obj)) {
            const value = obj[key];
            let date;

            if (isString(value) &&  (this.DATE_TIME_TIMEZONE_REGEXP.test(value))) {
                date = new Date(value);
                // the parsing above may fail, in which case we use isNaN to check if the date is valid
                if (isNaN(date.getTime())) {
                    return;
                }
                obj[key] = date;
            }
            this.deserializeDates(value);
        }

        return obj;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.