我正在将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),
};
},
答案 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);
},