Reputation: 5001
there is incoming string data which is date time format,
Its mapping this object fine;
import { types } from 'mobx-state-tree'
export const UserCard = types.model('UserCard').props({
id: types.number,
awarded_at: types.maybeNull(types.string),
})
at path "/0/awarded_at" value "2022-01-25T21:07:30.473502+00:00"
is not assignable to type: (Date | null)
but since its datetime trying this model just changed string to date;
export const UserCard = types.model('UserCard').props({
id: types.number,
awarded_at: types.maybeNull(types.Date),
})
then get this error in setting object;
at path "/0/awarded_at" value
"2022-01-25T21:07:30.473502+00:00"
is not assignable to type:(Date | null)
So how to map incoming string data to Date object
Upvotes: 5
Views: 778
Reputation: 112897
One common technique is to model it as a string like you have done in your first snippet, create a view that creates a Date
out of it, and use that instead:
import { types } from "mobx-state-tree";
export const UserCard = types
.model("UserCard")
.props({
id: types.number,
awarded_at: types.maybeNull(types.string)
})
.views((self) => ({
get awardedAtDate() {
return new Date(self.awarded_at);
}
}));
const userCard = UserCard.create({
id: 1,
awarded_at: "2022-01-25T21:07:30.473502+00:00"
});
console.log(userCard.awardedAtDate instanceof Date, userCard.awardedAtDate);
// true, Tue Jan 25 2022 22:07:30 GMT+0100 (Central European Standard Time)
If you don't like the approach above you can create a custom
type:
import { types } from "mobx-state-tree";
function validateDate(str) {
const date = Date.parse(str);
if (isNaN(date)) throw new Error("Invalid date");
return new Date(date);
}
export const IsoDate = types.custom({
name: "IsoDate",
fromSnapshot(value) {
return validateDate(value);
},
toSnapshot(value) {
return value.toISOString();
},
isTargetType(maybeDate) {
return maybeDate instanceof Date;
},
getValidationMessage(snapshot) {
// If we don't throw an error here when the snapshot is faulty (e.g. null),
// things like types.maybeNull(IsoDate) will not work properly
try {
validateDate(snapshot);
return "";
} catch (error) {
return error.message;
}
}
});
export const UserCard = types.model("UserCard").props({
id: types.number,
awarded_at: types.maybeNull(IsoDate)
});
const userCard = UserCard.create({
id: 1,
awarded_at: "2022-01-25T21:07:30.473502+00:00"
});
console.log(userCard.awarded_at instanceof Date, userCard.awarded_at);
// true, Tue Jan 25 2022 22:07:30 GMT+0100 (Central European Standard Time)
Upvotes: 4