-
The casting normally works correctly. It only fail when one of the fields is a date extracted from MySQL. That provokes the casting to fail:
Question Code
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
As it says in the error, // ...
self.setPitchers(resp.data.data.pitchers.pitchers.map(pitcher => {
...pitcher,
firstPitchedAt: new Date(pitcher.firstPitchedAt),
lastPitchedAt: new Date(pitcher.lastPitchedAt),
}))
// ... Alternatively, you can create your own custom type that would handle a string to a date conversion. |
Beta Was this translation helpful? Give feedback.
-
Hi @Zeioth! I recently answered a similar question on Stack Overflow. One common technique is to model it as a string, create a view that creates a 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 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) |
Beta Was this translation helpful? Give feedback.
-
Thank you so much guys, you helped me. In the end I used @BATCOH solution as it seem to be the convention in my project. setPitchers(list: IPitcher[]) {
try {
// Todo: model the mocked fields
const mappedList: any = list.map(pitcher => ({
uuid: pitcher.uuid,
organization: pitcher.organization,
firstPitchedAt: new Date(pitcher.firstPitchedAt),
lastPitchedAt: new Date(pitcher.lastPitchedAt),
pitchedSongsCount: pitcher.pitchedSongsCount,
pitchedToUsersCount: pitcher.pitchedToUsersCount,
approachStatus: pitcher.approachStatus,
pitchedToGenres: [
{
uuid: 'pts-3savwwhrg1',
name: 'metal',
parentGenre: null,
subGenres: [
{
uuid: 'pts-3savwshgi1',
name: 'folk-metal (mocked)',
},
],
},
{
uuid: 'pts-3savwwhrg2',
name: 'flamenco',
parentGenre: null,
subGenres: [
{
uuid: 'pts-3aavwwhgi1',
name: 'Sevillanas (mocked)',
},
],
},
],
pitchedToUsers: [
{
uuid: 'pts-3savwwhuu1',
firstName: 'User1 (mocked)',
},
{
uuid: 'pts-3savwwhuu2',
firstName: 'User2 (mocked)',
},
],
}))
self.list = cast(mappedList)
} catch (e) {
console.error('ERROR in setPitchers cast', e)
}
}, I tried the same thing server side, and I was able to, but having to re-build the promise was a pain and extra time I'm now allowed to spend, so, this is it. Thank you!! |
Beta Was this translation helpful? Give feedback.
As it says in the error,
types.Date
accepts numbers and Date instances as a value.But your value is a string. You can convert it to Date, something like that:
Alternatively, you can create your own custom type that would handle a string to a date conversion.