vuejs Invalid prop: type check failed for prop "modelValue"

477 views Asked by At

I'm encountering a type mismatch error with the v-file-input component in my Laravel, Vue.js, and Vuetify application. I'm attempting to update an image, but the component expects an array of File objects as its modelValue, while I'm providing a string. Here's the relevant code:

`<v-file-input v-model="form.img"></v-file-input>` 

Data using vue-form:

`form: new Form({ id: "", title: "", img: [],` // Initialized as an empty array }),

My Migration File:

`Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('title', 50);
            $table->string('img');
            $table->timestamps();
        });`

And my controller:

`public function store(Request $request)
    {

      
        $this->validate($request, [
            'title' => 'required|string|max:50|unique:categories,title',
        ]);
        $data = new Category();
        $data->title = $request->title;
        if ($request->hasFile('img')) {
            $image = $request->file('img')[0];
            $imageName = time() . '.' . $image->getClientOriginalExtension();
            try {
                $image->storeAs('public/images/categories', $imageName);
                $data->img = $imageName;
            } catch (Exception $e) {
                return response()->json([
                    'msg' => 'Error storing image: ' . $e->getMessage(),
                    'icon' => 'error'
                ], 422);
            }
        }
        $success = $data->save();
        if ($success) {
            return response()->json(['msg' => 'Stored Successfully &#128513;', 'icon' => 'success'], 200);
        } else {
            return response()->json([
                'msg' => 'Data not save in DB !!'
            ], 422);
        }
    }`

In vuejs, Im fetching data like that:

`<div v-if="allData && allData.data && allData.data.length > 0">
            <div class="table-responsive">
              <table class="table table-bordered table-striped align-middle text-center">
                <thead id="custom__table-head" class="table-primary">
                  <tr>
                    
                    <th>Image</th>
                    <th>
                      <span @click="sortByColumn('title')" class="col_sort">
                        Title
                        <v-icon v-if="sort_field === 'title'">
                          {{ sortDesc ? 'mdi-sort-descending' : 'mdi-sort-ascending' }}
                        </v-icon>
                      </span>
                    </th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="singleData in allData.data" :key="singleData.id" id="dataLoad">
                  
                    <td>
                      <v-card class="my-2" elevation="2" rounded>
                        <v-img :src="`/storage/images/categories/${singleData.img}`" height="64" width="" cover></v-img>
                      </v-card>
                    </td>
                    <td>{{ singleData.title }}</td>
                    <td>
                      <v-btn icon="mdi-lead-pencil" @click="editDataModel(singleData)" variant="plain"
                        color="blue-darken-3"></v-btn>
                      <v-btn @click="deleteData(singleData.id)" variant="plain" color="red-darken-2"
                        icon="mdi-delete"></v-btn>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
            <h5>Showing Page {{ pagination.current }} of Total {{ pagination.total }} pages</h5>
            <Pagination :pagination="pagination" :updatePage="getResults" />
          </div>
`

and the getResults() method:

` getResults(page = 1) {
      this.dataLoading = true;
      let link = this.currentUrl + '/index?page=' + page + '&per_page=' + this.per_page + '&search=' + this.searchQuery + '&sort_field=' + this.sort_field + '&sort_direction=' + (this.sortDesc ? 'desc' : 'asc');
      return axios
        .get(link)
        .then((response) => {
          console.log(link);
          this.allData = response.data;
          this.pagination.current = response.data.current_page;
          this.pagination.total = response.data.last_page;
          this.dataLoading = false;
        }).catch(error => {
          console.log(error.data)
        });
    },
`

Error: 'Invalid prop: type check failed for prop "modelValue". Expected Array, got String with value "image-name.jpg".

The error occurs when clicking the "Edit" button, which opens a modal for updating data.

I've tried initializing img as an empty array, but the issue persists.

Could you please guide me on how to resolve this type mismatch and ensure the v-file-input component receives the correct data type?

The v-file-input component should accept the empty array as its initial model value without errors. Upon file selection, the update:modelValue event should fire, allowing me to push the selected files into the array. The component should render correctly and allow for image updates.

1

There are 1 answers

0
ix.trc On

I assume you want to support multiple files with your input component, because form.img is an Array. Therefore you need to add the multiple prop as stated in the docs to support multiple files as inputs. https://vuetifyjs.com/en/components/file-inputs/#multiple

Edit: The component should look something like this

<v-file-input v-model="form.img" multiple></v-file-input>