How to work with pictures in an Vue form

  • 2021-10-25 05:41:07
  • OfStack

Question:

I have an form form in Vue for uploading blog posts, which has a range of titles, text, descriptions, snippets, and pictures. All 1 cuts are required. I set up an API in Express to deal with this problem. I tested normal in Postman, but I didn't know how to send the file to the database through the browser. I received 500 errors and I printed the data to the console with the picture field blank, so I'm sure that's the problem, but I just don't know what to do.

This is the form form for my front page:


<template>
 <div class="container">
  <div id="nav">
   <adminnav/>
  </div>
  <div id="create">
   <h1>Create new post</h1>
  </div>
  <div id="post">
   <body>
    <form>
     <label for="title">Title: </label>
     <textarea v-model=formdata.title rows="5" cols="60" name="title"
      placeholder="Enter text">
     </textarea>
     <br/>
     <label for="body">Body: </label>
     <textarea v-model=formdata.body rows="5" cols="60" name="body"
      placeholder="Enter text">
     </textarea>
     <br/>
     <label for="description">Description: </label>
     <textarea v-model=formdata.description rows="5" cols="60" name="description"
      placeholder="Enter text">
     </textarea>
     <br/>
     <label for="snippet">Snippet: </label>
     <textarea v-model=formdata.snippet rows="5" cols="60" name="snippet"
      placeholder="Enter text">
     </textarea>
     <br/>
     <label for="file">Upload photo: </label>
     <input
      class="form-control-file"
      type="file"
      accept="image/*"
      v-bind="formdata.photo"
     />
     <br/>
     <input id="submit" type="submit" value="submit" @click.prevent="createPost()"/>
    </form>
   </body>
  </div>
 </div>
</template>

<script>
import adminnav from '../components/adminnav.vue';
import PostService from '../service/PostService';

export default {
 name: 'createStory',
 components: {
  adminnav,
 },
 data() {
  return {
   formdata: {
    title: '',
    body: '',
    description: '',
    snippet: '',
    photo: null,
   },
  };
 },
 methods: {
  createPost() {
   console.log(this.formdata);
   /* eslint prefer-destructuring: 0 */
   const formdata = this.formdata;
   PostService.createPost(formdata)
    .then(() => {
     console.log('success');
    });
  },
 },
};
</script>

This is an POST request.


router.post("/add-story", upload.single('photo'), async(req, res) => {
 try{
  let post = new Post();
  post.title = req.body.title;
  post.description = req.body.description;
  post.photo = req.file.location;
  post.body = req.body.body;
  post.snippet = req.body.snippet;

  await post.save();

  res.json({
   status: true,
   message: "Successfully saved."
  });

 } catch(err) {
  res.status(500).json({
   success: false,
   message: err.message
  });
 }
});

Solution

Let's monitor the files <input> In change Events. This ensures that every time the user's upload behavior triggers updatePhoto Method and store the file data to the this.photo .


<input type="file" accept="image/*" class="form-control-file"
  @change="updatePhoto($event.target.name, $event.target.files)"
>

Encoding to collect all data and send requests


// vue Other parts of the component 
data () {
  return {
    title: '',
    body: '',
    description: '',
    snippet: '',
    photo: {} //  Store file data 
  };
},
methods: {
  updatePhoto (files) {
    if (!files.length) return;

    //  Store file data 
    this.photo = {
      name: files[0].name,
      data: files[0]
    };
  },
  createPost() {
    let formData = new FormData();

    formData.append('title', this.title);
    formData.append('body', this.body);
    formData.append('description', this.description);
    formData.append('snippet', this.snippet);
    formData.append('photo', this.photo.data, this.photo.name);

    PostService.createPost(formdata)
    .then(() => {
      console.log('success');
    });
  }
}
// vue Other parts of the component 

Obviously, I skipped a lot of things, such as the whole vue component structure, which I believe has nothing to do with this problem, and a few checks to ensure that the file data is available before starting the request. This is an idea about how to get file data, so I hope this answer can enlighten you.

The above is how to deal with images in the Vue form in detail, more on the Vue form to deal with images of information please pay attention to other related articles on this site!


Related articles: