I have:
an issue with this error
bluebird.js:95 Uncaught Error: [mobx-state-tree] You are trying to read or write to an object that is no longer part of a state tree. (Object type was 'Schedule').
when trying to update a model Schedule that is part of a model ScheduleStore array.
This is part of my model
const ScheduleStore = types.model("ScheduleStore", {
name: types.string,
schedules: types.maybe(types.array(Schedule)),
})
and when I leave it like this I get the above error.
If I change it to
const ScheduleStore = types.model("ScheduleStore", {
name: types.string,
schedules: types.maybe(types.array(types.frozen)),
})
then everything works fine but that way doesnt feel correct..
can someone please help me understand what I am doing wrong here... I am new to MST but learning very quickly. Thanks
Nothing seems wrong with the ScheduleStore model so please post the code of the Schedule model and the updates that lead to that error as well.
the Schedule looks like
const Schedule = types
.model("Schedule", {
id: types.maybe(types.string),
created: types.Date,
title: types.string,
description: types.string,
done: types.boolean,
assigned: types.array(types.frozen),
start: types.Date,
end: types.Date
})
and I am updating a rethinkdb and then using the changefeed to update the mobx store like this
updateScheduleToDb(schedule) {
r.table('schedules').get(schedule.id).update(schedule).run(connection, (err, cursor) => {
if (err) throw err;
console.log(cursor)
});
},
connectToChangesDB(conn) {
let arr = [];
r.table('schedules').changes({
includeInitial: true,
includeStates: true,
includeTypes: true
}).run(conn, (err, cursor) => {
if (err) throw err;
connection = conn;
console.log("connection in schedule store", conn)
cursor.each((err, row) => {
if (err) throw err;
console.log("Logging changes in schedule store::", JSON.stringify(row, null, 2));
switch (row.type) {
case 'initial':
arr.push(row.new_val)
break;
case 'remove':
self.removeById(row.old_val.id);
break;
case 'change':
self.update(row.new_val)
break;
case 'add':
self.insert(row.new_val)
break;
}
if (row.state === 'ready') {
self.setInitialSchedules(arr);
}
})
});
},
any help on this would be appreciated in order to save my brain and energy I had to just set it to frozen type and move on until I can get some help on this.. please and thanks!
This error in general means you are writing it after it has been removed from the tree. Which is very well possible as your process is asynchronous. You might want to check isAlive(self) before making changes to it, or reason why you still have an async process running for the object, after removing / replacing it in the tree, should you be cleaning up some connection, etc.
The error basically means the update is pointless, as the thing you are trying to update is not part of the tree anymore, which often indicates that there is a logical error somewhere else.
Hope that helps!
Closed since answered and no further activity
@mweststrate Not sure if I should revive this, but I am coming across a similar issue, except when passing an mst object as a prop to a functional component. I have tried using isAlive(self) to no avail... scratching my head with this one.
getAllStories is called in componentDidMount(){...}.
On the first render, no error, however on subsequent renders after unmounting once it throws.
model:
const StoryModel = types
.model('StoryModel', {
content: types.maybe(types.string),
description: types.maybe(types.string),
id: types.maybeNull(types.string),
parentStoryId: types.maybeNull(types.string),
profileId: types.maybeNull(types.string),
title: types.maybe(types.string),
isCloned: types.maybe(types.boolean),
author: types.maybeNull(types.string),
likes: types.maybeNull(types.integer),
usersWhoLiked: types.array(LikesModel),
})
const StoryStore = types
.model('StoryStore', {
fetchingStory: types.optional(types.boolean, false),
fetchingStories: types.optional(types.boolean, false),
story: types.maybeNull(StoryModel),
stories: types.array(StoryModel),
selectedStory: types.optional(types.string, ''),
cloningStory: types.optional(types.boolean, false),
currentCloneId: types.maybe(types.string),
})
action:
const getAllStories = flow(function* () {
self.fetchingStories = true
const { data: { allStories } } = yield client.query({
query: AllStories,
})
self.fetchingStories = false
self.setStories(allStories)
})
setStories:
const setStories = (stories) => {
applySnapshot(self.stories, stories)
// self.stories = stories
}
_this throws the mentioned error_:
{storyStore.stories.map(story => (
<StoryCard story={story} key={story.id} />
))}
_this is fine_:
// note that this is what StoryCard renders
{storyStore.stories.map(story => (
<Card key={story.id}>
<span>{story.title}</span>
<span>{story.id}</span>
<h5>Likes: {story.likes}</h5>
<Link to={`/story/preview/${story.id}`}>
<ButtonPrimary>
View
</ButtonPrimary>
</Link>
</Card>
))}
I can open a new issue if that is better, couldn't find anything related to this searching through docs/past issues 馃槄
@kysley did you find any solution for you problem? Thank you!
Same here. Exactly the problem @kysley mentioned. Any ideas?
My solution is wrap any observables with observer, it's resolved.
Ref: https://mobx.js.org/react-optimizations.html#render-lists-in-dedicated-components
Most helpful comment
@mweststrate Not sure if I should revive this, but I am coming across a similar issue, except when passing an mst object as a prop to a functional component. I have tried using isAlive(self) to no avail... scratching my head with this one.
getAllStoriesis called in componentDidMount(){...}.On the first render, no error, however on subsequent renders after unmounting once it throws.
model:
action:
setStories:
_this throws the mentioned error_:
_this is fine_:
I can open a new issue if that is better, couldn't find anything related to this searching through docs/past issues 馃槄