Nativewscript-vue graphql:TypeError:无法读取未定义的属性“map”

时间:2021-03-13 22:58:56

标签: android vue.js graphql nativescript apollo

我正在使用 Nativescript-vue 和 Vue-apollo 创建电子商务应用程序。产品列表页面正常工作,但当我进入单个产品页面时出现此错误:

System.err: An uncaught Exception occurred on "main" thread.
System.err: Calling js method run failed
System.err: TypeError: Cannot read property 'map' of undefined
System.err: 
System.err: StackTrace:
System.err: (file: src/pages/products/index.vue?2e29:57:52)
System.err:     at update(file: src/pages/products/index.vue?2e29:56:35)
System.err:     at nextResult(file: node_modules/vue-apollo/dist/vue-apollo.esm.js:985:43)
System.err:     at notifySubscription(file: node_modules/zen-observable/lib/Observable.js:135:17)
System.err:     at onNotify(file: node_modules/zen-observable/lib/Observable.js:179:2)
System.err:     at next(file: node_modules/zen-observable/lib/Observable.js:235:6)
System.err:     at (file: src/src/core/ObservableQuery.ts:701:58)
System.err:     at iterateObserversSafely(file: src/src/core/ObservableQuery.ts:701:22)
System.err:     at next(file: src/src/core/ObservableQuery.ts:662:12)
System.err:     at invoke(file: src/src/core/QueryManager.ts:518:28)
System.err:     at (file: src/src/core/QueryManager.ts:644:8)
System.err:     at (file: src/src/core/QueryManager.ts:1091:12)
System.err:     at (file: src/src/core/QueryManager.ts:1087:23)
System.err:     at QueryManager.broadcastQueries(file: src/src/core/QueryManager.ts:1085:17)
System.err:     at (file: src/src/core/QueryManager.ts:1237:15)
System.err:     at next(file: node_modules/zen-observable/lib/Observable.js:322:22)
System.err:     at notifySubscription(file: node_modules/zen-observable/lib/Observable.js:135:17)
System.err:     at onNotify(file: node_modules/zen-observable/lib/Observable.js:179:2)
System.err:     at next(file: node_modules/zen-observable/lib/Observable.js:235:6)
System.err:     at (file: src/src/util/observables.ts:12:49)
System.err:     at next(file: src/src/util/observables.ts:12:18)
System.err:     at notifySubscription(file: node_modules/zen-observable/lib/Observable.js:135:17)
System.err:     at onNotify(file: node_modules/zen-observable/lib/Observable.js:179:2)
System.err:     at next(file: node_modules/zen-observable/lib/Observable.js:235:6)
System.err:     at next(file: src/src/index.ts:61:21)
System.err:     at notifySubscription(file: node_modules/zen-observable/lib/Observable.js:135:17)
System.err:     at onNotify(file: node_modules/zen-observable/lib/Observable.js:179:2)
System.err:     at next(file: node_modules/zen-observable/lib/Observable.js:235:6)
System.err:     at (file: src/src/httpLink.ts:142:19)
System.err:     at com.tns.Runtime.callJSMethodNative(Native Method)
System.err:     at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1302)
System.err:     at com.tns.Runtime.callJSMethodImpl(Runtime.java:1188)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1175)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1153)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1149)
System.err:     at com.tns.gen.java.lang.Runnable.run(Runnable.java:17)
System.err:     at android.os.Handler.handleCallback(Handler.java:883)
System.err:     at android.os.Handler.dispatchMessage(Handler.java:100)
System.err:     at android.os.Looper.loop(Looper.java:214)
System.err:     at android.app.ActivityThread.main(ActivityThread.java:7356)
System.err:     at java.lang.reflect.Method.invoke(Native Method)
System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

这是我的代码:

src/pages/products/index.vue

<template lang="pug">
  Page(actionBarHidden="true")
    ScrollView
      RadListView(
        for="product in products"
        layout="staggered"
        :gridSpanCount="2"
        @itemTap="openProduct"
      )
        v-template
          StackLayout(class="rounded m-1" v-shadow="2")
            Image(:src="`${mediaUrl}/${product.images[0]}`")
            StackLayout(class="p-2")
              Label(textWrap="true")
                FormattedString
                  Span(:text="product.name" class="text-xl")
                  Span(text="\n" class="text-xs")
                  Span(:text="`R$ ${product.price}`" class="text-base")
</template>

<script lang="ts">
import { gql } from "apollo-boost"
import ProductPage from "@/pages/products/_id/index.vue"
import { ProductNode } from "~/types/types"

interface ProductEventType {
  index: Number,
  item: ProductNode
}

export default {
  apollo: {
    products: {
      query: gql`
        query Products {
          products {
            edges {
              node {
                id
                name
                description
                price
                images(last: 1) {
                  edges {
                    node {
                      image
                    }
                  }
                }
              }
            }
          }
        }
      `,
      update: (data) => {
        data = data.products.edges.map((item: any) => {
          item.node.images = item.node.images.edges.map((image: any) => {
            return image.node.image
          })

          return item.node
        })

        return data
      }
    }
  },
  data: {
    mediaUrl: MEDIA_FILES_URL
  },
  methods: {
    openProduct(event: ProductEventType) {
      this.$navigateTo(ProductPage, {
        frame: "productsTab",
        transition: {
          name: "slideLeft"
        },
        props: {
          preData: event.item
        }
      })
    }
  }
}
</script>

src/pages/products/_id/index.vue

<template lang="pug">
  Page(actionBarHidden="true" @loaded="loaded")
    ScrollView
      StackLayout(v-if="$apollo.loading")
      StackLayout(v-else)
        Carousel
          CarouselItem(v-for="image in product.images" :key="image")
            Image(:src="`${mediaUrl}/${image}`")
        Label(:text="product.name" class="leading-none text-3xl" textWrap="true")
        Label(:text="product.price" class="text-2xl mt-2")
        Label(:text="product.description" class="leading-none text-base mt-2" textWrap="true")
</template>

<script lang="ts">
import { gql } from "apollo-boost"

export default {
  apollo: {
    product () {
      return {
        query: gql`
          query Product($id: ID!) {
            product(id: $id) {
              description
              images(first: 2) {
                edges {
                  node {
                    image
                  }
                }
              }
              stocks {
                edges {
                  node {
                    size {
                      size
                    }
                    color {
                      color
                    }
                    quantity
                  }
                }
              }
            }
          }
        `,
        variables: {
          id: this.preData.id
        },
        skip: this.skipQuery,
        update: (data: any) => {
          data = data.product
          data.images = data.images.edges.map((image: any) => {
            return image.node.image
          })
          data.stocks = data.stocks.edges.map((stock: any) => {
            stock = stock.node
            stock.size = stock.size.size
            stock.color = stock.color.color

            return stock
          })

          data.images.unshift(this.product.images[0])

          data = { data, ...this.preData }

          return data
        }
      }
    }
  },
  data() {
    return {
      mediaUrl: MEDIA_FILES_URL,
      skipQuery: false
    }
  },
  props: {
    preData: {
      type: Object,
      required: true
    }
  },
  methods: {
    loaded() {
      this.skipQuery = false
    }
  }
}
</script>

您可能首先想到的错误是在“src/pages/products/_id/index.vue”中的“update”函数中,但我在没有它的情况下进行了测试,并且发生了同样的错误。

我怀疑这不是与我的代码相关的错误,对我来说它看起来像是一个错误。

1 个答案:

答案 0 :(得分:0)

我相信,您正在尝试根据标题和错误日志映射一个不存在的数组。

在检查您的代码时,错误似乎来自父 src/pages/products/index.vue

在你的阿波罗中:

...
      update: (data) => {
        data = data.products.edges.map((item: any) => {
          item.node.images = item.node.images.edges.map((image: any) => {
            return image.node.image
          })

          return item.node
        })

        return data
      }
...

我认为,因为您请求查询中的最后一个 images(last: 1) {,您将获得一个对象而不是一个数组。因此 item.node.images = item.node.images.edges.map((image: any) => { 会导致错误。在第 57 行,错误日志告诉我们:`System.err: (file: src/pages/products/index.vue?2e29:57:52)``