Ryley38
Ryley38

Reputation: 361

Vue3 : Why my property is not defined on instance?

I am building a dummy app with a component in a component passing properties. I use firebase to store data and try to read the data onMounted.

I am getting this error but I don't understand how to fix it. What I am missing?

[Vue warn]: Property "names" was accessed during render but is not defined on instance. 
  at <CrewList modelValue= (3) [{…}, {…}, {…}]

App.vue import several components. I declare a const name with an interface. OnMounted data are read and populated in const names. The console.log(doc.id, " => ", doc.data()) shows that data is properly read. But nothing is showing up in the app.

app.vue

<script setup lang="ts">
import { ref, onMounted } from "vue";
import type { NameInterface } from "./name.interface";
import TheHeader from "./components/Header.vue";
import TheFooter from "./components/Footer.vue";
import Crew from "./components/Crew.vue";
import { collection, query, where, getDocs } from "firebase/firestore";
import { db } from "@/firebase";

const names = ref<NameInterface[]>([]);

onMounted(async () => {
  const q = query(collection(db, "crew"));
  let crewNames = [];
  const querySnapshot = await getDocs(q);
  querySnapshot.forEach((doc) => {
    console.log(doc.id, " => ", doc.data());
    const crewName = {
      id: doc.id,
      name: doc.data().name,
    };
    crewNames.push(crewName);
  });
  names.value = crewNames;
  console.log("names populated");
});
</script>

<template>
  <div class="app-container">
    <TheHeader class="header" />
    <Crew :names="names" class="crew" />
    <TheFooter class="footer" />
  </div>
</template>

Crew.vue

    <script setup lang="ts">
    import type { NameInterface } from "@/name.interface";
    import { ref } from "vue";
    import CrewList from "./CrewList.vue";
    
    defineProps<{
      names: NameInterface[];
    }>();
    const nameText = ref<string>("");
    
    const addName = () => {
      const newName = {
        name: nameText.value,
      };
      names.push(newName);
      nameText.value = "";
    };
    </script>
    
    <template>
      <div class="full-w d-flex flex-column align-items-center">
        <div class="form-container d-flex align-items-center">
          <form action="" @submit.prevent="addName">
            <input
              placeholder="test"
              type="text"
              v-model="nameText"
              class="mr-30"
            />
            <button class="btn" :disabled="!nameText">Envoyer</button>
          </form>
        </div>
        <div class="container mt-40">
          <CrewList v-model="names" :nameText="nameText" />
        </div>
      </div>
    </template>

**CrewList.vue**

<script setup lang="ts">
import type { NameInterface } from "@/name.interface";

defineProps<{
  modelValue: NameInterface[];
  nameText: string;
}>();
</script>

<template>
  <div class="container d-flex flex-rows justify-content-center pb-30">
    <div v-for="n in names">
      <p>{{ n.name }}</p>
    </div>
  </div>
</template>

<style lang="scss" scoped>

CrewList.app

<script setup lang="ts">
import type { NameInterface } from "@/name.interface";

defineProps<{
  modelValue: NameInterface[];
  nameText: string;
}>();
</script>

<template>
  <h2 class="full-w d-flex justify-content-center mt-40 mb-20">
    Membres de l'équipage
  </h2>
  <div class="container d-flex flex-rows justify-content-center pb-30">
    <div v-for="n in names">
      <p>{{ n.name }}</p>
    </div>
  </div>
</template>

NameInterface

export interface NameInterface {
  name: string;
}

Upvotes: 0

Views: 2160

Answers (1)

Andr&#233;
Andr&#233;

Reputation: 7

In crewList when you use <div v-for="n in names"> i think that what you wanna use is <div v-for="n in modelValue">. property name cannot be found because names is not a variable declared

Upvotes: 1

Related Questions