Types.reference and types.identifier crashing application upon deleting User Reference; Error: [mobx-state-tree] Failed to resolve reference #2134
-
Hello MST Maintainers, Here is my issue explained in a more simplified manner: I have a UserModel: export const UserModel = types
.model("User")
.props({
id: types.identifier, // <------ IDENTIFIER
firstName: "",
lastName: "",
username: "",
profileImage: types.maybeNull(types.string),
})
})) and I have a FriendshipModel: export const FriendshipModel = types
.model("Friendship")
.props({
id: types.identifier,
status: types.frozen<FRIENDSTATUS>(),
friend: UserModel, // <------ Where the actual User Data is stored in the tree
initiatedByFriend: false,
createdAt: "",
}) and I have a MessageModel: export const MessageModel = types
.model("Message")
.props({
id: types.identifier,
sender: types.safeReference(UserModel), // <------ ISSUE IS HERE
receiver: types.safeReference(UserModel), // <------ ISSUE IS HERE
createdAt: "",
})
})) I'm essentially reaching out to my API on AWS right upon app load: useEffect(() => {
;(async function load() {
setIsLoading(true)
try {
await userStore.fetchAllFriendshipsWithCurrentUser()
await messageStore.fetchUnreadMessagesFromDB()
} catch (err) {
console.log("Error with loading messages or friends", err)
}
setIsLoading(false)
})()
}, [messageStore, userStore, userStore.currentUser?.profileImage]) So everything works PERFECTLY under all normal circumstances. However, as soon as I:
The whole app crashes with the error: I tried using Obviously, there are a few approaches I have considered.... For example, if a user "unfriends" someone, I just delete all the past messages that were ever exchanged with that user in the AWS database or somehow exclude them in the fetch call... I really would prefer not to delete the data just because each user should still be able to see their messages. I know there is a good solution out there, thanks in advance for the help! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hey @ChristopherGabba - thanks for the very detailed question. Sorry it took a little while to get to you, I was busy this weekend haha. You've got a lot of the patterns I would recommend, including the Might look like this for you: export const MessageModel = types
.model("Message")
.props({
id: types.identifier,
sender: types.safeReference(UserModel).onInvalidate((sender) => {
// Handle the case where sender is deleted
// For example, set sender to a default user or handle it according to your logic
}),
receiver: types.safeReference(UserModel).onInvalidate((receiver) => {
// Handle the case where receiver is deleted
// For example, set receiver to a default user or handle it according to your logic
}),
createdAt: "",
}) Let me know if that works for you or not. I think excluding the data in your fetch is also a reasonable approach, but hopefully this is the simplest change to your existing code and lets you move forward. |
Beta Was this translation helpful? Give feedback.
Hey @ChristopherGabba - thanks for the very detailed question. Sorry it took a little while to get to you, I was busy this weekend haha.
You've got a lot of the patterns I would recommend, including the
safeReference
. I think the only thing you're missing is theonInvalidatedHook
. That should clean up your stale data and allow you to use thesafeReference
approach that's working.Might look like this for you: