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

Posted

技术标签:

【中文标题】Nativewscript-vue graphql:TypeError:无法读取未定义的属性“地图”【英文标题】:Nativewscript-vue graphql: TypeError: Cannot read property 'map' of undefined 【发布时间】:2021-06-11 14:55:53 【问题描述】:

我正在使用 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”中的“更新”函数中,但我在没有它的情况下进行了测试,并且出现了同样的错误。

我怀疑这不是与我的代码有关的错误,它对我来说似乎是一个错误。

【问题讨论】:

【参考方案1】:

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

在检查您的代码时,错误似乎来自父级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) =&gt; 导致错误。在第 57 行,错误日志告诉我们:`System.err: (file: src/pages/products/index.vue?2e29:57:52)`

【讨论】:

以上是关于Nativewscript-vue graphql:TypeError:无法读取未定义的属性“地图”的主要内容,如果未能解决你的问题,请参考以下文章

GraphQl 和 insomnia 桌面客户端无法使用 graphql.org/swapi-graphql

使用 Express-GraphQL 的 GraphQL 订阅

数组中类型为 graphql 对象的 GraphQL 字段

Graphql 突变查询不适用于 express-graphql

[GraphQL] Query GraphQL Interface Types in GraphQL Playground

GraphQL - 无法缓存数据是 GraphQL 的一大弱点?