无法添加/删除密封的数组元素

时间:2017-09-18 16:11:55

标签: vue.js graphql apollo

我正在将graphql api调用与数组修改结合起来。

async deletePhoto(photoId, driveId, index) {

  this.property.photos.splice(index, 1);

  await api.photos.remove(this.property.id, photoId, driveId);
},

api致电:

  const remove = async (propertyId, photoId, driveId) => {

  const mutation = gql`
    mutation photoDelete($propertyId: Int!, $photoId: String!, $driveId: String!) {
      deletePropertyPhoto(propertyId: $propertyId, photoId: $photoId, driveId: $driveId)
    }
  `;

  const result = await apolloClient.mutate({
    mutation,
    variables: {
      propertyId,
      photoId,
      driveId,
    },
  });

  console.log(result);
  return result;
};

问题:

Uncaught (in promise) TypeError: Cannot add/remove sealed array elements
    at Array.splice (<anonymous>)
    at VueComponent._callee3$ (http://localhost:3030/_nuxt/3.js:284:38)
    at tryCatch (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:26549:40)
    at Generator.invoke [as _invoke] (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:26787:22)
    at Generator.prototype.(anonymous function) [as next] (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:26601:21)
    at step (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:8714:30)
    at http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:8732:14
    at Promise (<anonymous>)
    at F (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:8036:28)
    at VueComponent.<anonymous> (http://localhost:3030/_nuxt/vendor.bundle.5559a1f55cb4b1323e8d.js:8711:12)

是什么让这个错误如此奇怪?当我删除api调用时,它工作正常。这对我没有任何意义,因为api调用与数组修改无关。

修改 这很疯狂,有时出现错误,有时拼接工作正常。这是我遇到过的最随机的错误。

EDIT2: 在获取属性(和照片)时,我已经创建了graphql结果的对象副本:

async asyncData({ params }) {
    const fetchedProperty = await api.properties.findOne(params.id);
    return {
      oldProperty: fetchedProperty,
      property: Object.assign({}, fetchedProperty),
    };
  },

2 个答案:

答案 0 :(得分:0)

您的API调用显然正在返回一个对象(fetchedProperty),其中photos数组已通过Object.seal密封。

您正在将property数据属性设置为Object.assign({}, fetchedProperty),这会将fetchedProperty中每个属性的值分配给空数组。

这仍然意味着photos(密封数组)的值被设置为分配给property数据属性的空对象。

您需要显式复制photos数组的值,并将其设置为data属性的photos属性。也许是这样的:

async asyncData({ params }) {
  const fetchedProperty = await api.properties.findOne(params.id);
  let property = Object.assign({}, fetchedProperty);
  let property.photos = [...fetchedProperty.photos];

  return {
    oldProperty: fetchedProperty,
    property: property
  };
}

答案 1 :(得分:0)

删除密封对象的另一种方法是使用slice

this.property.photos = this.property.photos.slice(0, idx).concat(this.property.photos.slice(idx + 1));

在你的职能中:

async deletePhoto(photoId, driveId, index) {
    this.property.photos = this.property.photos.slice(0, idx).concat(this.property.photos.slice(idx + 1));
    await api.photos.remove(this.property.id, photoId, driveId);
},