0

New to Vue and stack...please be gentle...

Problem/question: Recently implemented a Suspense wrapper at the view level and lost ability to use props passed through to the component level. If I remove Suspense at the view level then my component level code receives the prop value but if I add Suspense to the view level then the prop value in the component is not defined. Why?

Given current approach I would like the prop value and to be able to use async setup. Is this not possible?

The error message I get when Suspense is used is: [Vue warn]: Extraneous non-props attributes (lId) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.

Background and code:

I implemented a wrapper around a view level component because it was required to use async setup() within the component contained (ex: component has a composable call requiring await to get data critical to remaining step, etc).

Is the issue related to async setup? Meaning, if you use async setup(props) vs setup(props) do you lose the ability to inherit props value?

ROUTER CODE:

  {
    path: '/events/:lId',
    name: 'events',
    component: Home,
    beforeEnter: requireAuth,
    props: true
  },

VIEW LEVEL:

<template>
  <Suspense>
    <template #default>
      <EventDash />
    </template>
    <template #fallback>
      Loading...
    </template>
  </Suspense>
</template>

<script>
import EventDash from '@/components/EventDash.vue'
export default {
  name: 'home',
  components: { EventDash }
}
</script>

COMPONENT LEVEL (relevant snippet from EventDash):

export default {
  name: "eventDash",
  props: ["lId"],
  async setup(props) {
    console.log('prop', props.lId) // undefined when Suspense used at view level
    // get user default location
    const userHome = await getUserHome()
...do other stuff reliant on userHome value

Related posts I found that were either unanswered or did not solve include:

vue3 how to use suspense passing async props to component

How to use vue 3 suspense component with a composable correctly?

Any advice/enlightenment appreciated.

[EDIT] TRIMMED COMPONENT LEVEL TO FURTHER ILLUSTRATE:

       export default {
          name: "eventDash",
          props: ["lId"],
          async setup(props) {
            console.log('prop', props.lId) // undefined when async
          }
        }

-vs-

       export default {
          name: "eventDash",
          props: ["lId"],
          setup(props) {
            console.log('prop', props.lId) // DEFINED
          }
        }
BGMX
  • 25
  • 7
  • A demo that can be debugged would make it easier to solve for those who aren't aware of this issue. Currently you seem to rely on attribute fallthrough https://vuejs.org/guide/components/attrs.html#attribute-inheritance in nested component, I'd expect it to work here but any way, this is specific to how Suspense works internally, and it's still experimental. Did you try to avoid a fallthrough? – Estus Flask Sep 04 '22 at 13:43
  • Fallthrough implies the prop value would "fall through" to the component which is the desired outcome. The value of the prop "lId" is readable in the component EventDash.vue ONLY when async is removed from setup. As soon as I make async setup then I lose access to the value of the prop and need to add Suspense to the view level. Maybe the question would be better worded as, "how to access props within asycn setup(props)?" As soon as I make setup async I lose access to the prop which is confusing behavior to a novice. – BGMX Sep 04 '22 at 14:33
  • Is there when `setup` is sync? This is quite complex matter for a novice. Again, the problem is that you rely on fallthrough behaviour here. It's ok as long as it's documented, but in case of suspense, it's that receives props, and it's unknown what happens then, I'm not sure this was specified anywhere. Suspense is experimental and may have problems or changes before it becomes stable. Did you try `` and `inheritAttrs: false` in view comp. In case this works, this will be an answer – Estus Flask Sep 04 '22 at 14:58
  • Thank you. Based on your comments, lack of resources to solve this type of problem combine with my relative lack of JS experience I think I am going to try and re-write it in a way that can avoid async setup perhaps by moving the async "get this data so you can get that data so you can render result" requirement to a composable. Been a developer for long time but have always lived in a procedural syncronous world. Tough transition! Thanks again. – BGMX Sep 05 '22 at 14:17
  • Not sure if there's a problem, what you tried is legit if the intention is to specifically show "Loading..." while loading a piece route of data - otherwise you could load it earlier on route navigation. The only problem here is passing props to EventDash. And btw, they are duped as route params, `useRoute` – Estus Flask Sep 05 '22 at 14:23

0 Answers0