javascriptreact-nativemobxstate-managementmobx-state-tree

Cannot copy mst model data from one model to other


I'm trying to make a news app which can take response from news api and store it in newsFeed and then user can mark some news as favourites and then store these fav to new model favourite

this is the error i'm getting

Error: [mobx-state-tree] Cannot add an object to a state tree if it is already part of the same or another state tree. Tried to assign an object to '/newsStore/favorite/0', but it lives already at '/newsStore/newsFeed/0', js engine: hermes here's my news model

export const NewsModel = types
  .model('News')
  .props({
    newsFeed: types.array(News),
    favorite: types.array(News),
    totalResults: types.maybeNull(types.number),
    newsUserTask: types.optional(AsyncTask, {}),
  })

this is how i'm calling api and storing it in newsFeed

.actions(self => {
    const newsCall = (page: number, feed: boolean) =>
      runTask(self.newsUserTask, function* ({ exec }) {
        const result = yield* toGenerator(
          self.environment.baseApi.newsFeed(page),
        );
        exec(() => {
          if ((result as NewsTypeResponse).status === 'ok') {
      

            if (self.newsFeed.length) {
              if (page < Math.ceil(self.totalResults / 10)) {
                self.newsFeed = castToSnapshot([
                  ...self.newsFeed,
                  ...(result as NewsTypeResponse).articles,
                ]);
              } else {
                self.rootStore.errorStore.setError(
                  translate('errors.endOfPage'),
                );
              }
              self.newsFeed = castToSnapshot([
                ...self.newsFeed,
                ...(result as NewsTypeResponse).articles,
              ]);
            } else {
              if (feed) {
                self.totalResults = castToSnapshot(
                  (result as NewsTypeResponse).totalResults,
                );
                self.newsFeed = castToSnapshot(
                  (result as NewsTypeResponse).articles,
                );
              } else {
                self.newsData = castToSnapshot(
                  (result as NewsTypeResponse).articles,
                );
              }

              console.log('load more working');
            }
            console.log('working');
          } else {
            console.log('not working');
          }
        });
      });

    return { newsCall };
  })

and this is how i'm trying to store in favorite

.actions(self => ({
    setFav(item: NewsTypes) {
      self.favorite.push(item);
    },
  }))

how can i do this i tried following some solutions like this Cannot add an object to a state tree if it is already part of the same or another state tree


Solution

  • You could model your favorite array to be an array of references to News instead, and just add the identifier to this array in the setFav action (granted that your News model has a types.identifier or types.identifierNumber). More information about these concepts can be found here.

    export const NewsModel = types
      .model('News')
      .props({
        newsFeed: types.array(News),
        favorite: types.array(types.reference(News)),
        totalResults: types.maybeNull(types.number),
        newsUserTask: types.optional(AsyncTask, {}),
      })
      .actions(self => ({
        setFav(item: NewsTypes) {
          self.favorite.push(item.id);
        },
      }));