gidaban79's avatar

Update record in DB with file - FormData

Hello Guys hope you are well?

I am facing some problem with update and upload image by vue js.

Here is my component:

<template>
  <div>

    <div class="min-vh-100">
      <!--Share icons-->
      <div class="row">
        <div class="col-12">
          <div class="alert alert-outline-success">
            <span class="badge badge-success badge-pill mr-3">Share</span>
            <span class="mr-4 pr-2">This is your unique link to share -
                  <a :href="board.share_url" target="_blank">{{ board.share_url }}</a>
                </span>
            <span>
              <a :href="tweeter_share">
                <button type="button" class="btn btn-sm rounded-circle btn-icon-only mt-n2">
                  <span class="btn-inner--icon">
                    <span><img src="/assets/img/social_media/twitter.svg" style="height: 20px" alt="twitter"
                               title="twitter"></span>
                  </span>
                </button>
             </a>
             <a :href="fb_share">
              <button type="button" class="btn btn-sm rounded-circle btn-icon-only mt-n2">
                <span class="btn-inner--icon">
                  <span><img src="/assets/img/social_media/facebook.svg" style="height: 20px" alt="facebook"
                             title="facebook"></span>
               </span>
              </button>
             </a>
              <a :href="pinterest_share">
                <button type="button" class="btn btn-sm rounded-circle btn-icon-only mt-n2">
                                   <span class="btn-inner--icon">
                                        <span><img src="/assets/img/social_media/pinterest.svg" style="height: 20px"
                                                   alt="pinterest" title="pinterest"></span>
                                    </span>
                                </button>
                            </a>
                        </span>
          </div>
        </div>
      </div>
      <!--Share icons-->
      <div class="d-flex justify-content-between align-items-center">
        <div class="1">
          <div class="h2" v-text="board.name"></div>
          <p v-text="board.description"></p>
        </div>
        <div class="2">
          <span>Views - </span><strong><span v-text="board.views"></span></strong>
        </div>
      </div>
      <div class="row">
        <idea-board-new-item @newItem="updateBoard"/>
      </div>

      <div class="row">
        <div class="col-md-3" v-for="(item,index) in board.items">
          <div class="card shadow-none">
            <idea-board-item
                v-bind:item="item"
                @removeElement="removeElementAlert(item.uuid,index)"
                @editElement="editElement"/>
          </div>
        </div>
      </div>

      <div class="container-fluid">
        <div class="col-12 text-center">
          <button type="button" class="btn btn-sm btn-danger" @click.prevent=deleteBoard>
            Delete board
          </button>
        </div>
      </div>

    </div>
    <!--    edit item modal-->
    <div class="modal modal-fluid fade" id="edit-item" tabindex="-1" aria-hidden="true">
      <div class="modal-dialog modal-xl">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">Edit item</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <div class="row">
              <div class="col-6">
                <div class="form-group pt-2">
                  <label for="edit_name">Name</label>
                  <input
                      type="text" name="name" id="edit_name"
                      class="form-control form-control-sm" v-model="form.name"
                      :class="[{'is-invalid' : form.errors.has('name')}]"
                      @keydown="form.errors.clear('name')">
                  <span class="invalid-feedback" v-show="form.errors.has('name')"
                        v-text="form.errors.get('name')"></span>
                </div>
                <div class="form-group">
                  <label for="edit_description">Description</label>
                  <textarea name="description" id="edit_description" rows="3"
                            class="form-control form-control-sm" v-model="form.description"
                            @keydown="form.errors.clear('description')"
                            :class="[{'is-invalid': form.errors.has('description')}]"></textarea>
                  <span class="invalid-feedback" v-show="form.errors.has('description')"
                        v-text="form.errors.get('description')"></span>
                </div>
                <div class="form-group">
                  <label for="edit_link">Add links (youtube/vimeo etc..)</label>
                  <input type="text" name="link" id="edit_link" class="form-control form-control-sm" v-model="form.link"
                         :class="[{'is-invalid' : form.errors.has('link')}]"
                         @keydown="form.errors.clear('link')">
                  <span class="invalid-feedback" v-show="form.errors.has('link')"
                        v-text="form.errors.get('link')"></span>
                </div>

                <div class="form-group">
                  <input type="file"
                         ref="file"
                         name="image"
                         id="edit_image"
                         accept="image/*"
                         @change="onFileSelected"
                         class="custom-input-file custom-input-file--2"
                         :class="[{'is-invalid' : form.errors.has('image')}] ">
                  <label for="edit_image">
                        <span><img src="/assets/bootstrap/icons/image-fill.svg" alt="Image"
                                   title="image" class="mr-2 make-icon-white"></span>
                    <span>Choose a photo...</span>
                  </label>
                  <span class="invalid-feedback" v-show="form.errors.has('image')"
                        v-text="form.errors.get('image')"></span>
                </div>
              </div>

              <div class="col-6">
                <div v-if="this.form.name">
                  title:
                  <h4>{{ this.form.name }}</h4>
                </div>
                <div v-if="this.form.description"><small>Description:</small>
                  <p>{{ this.form.description }}</p>
                </div>
                <div v-if="this.form.link">
                  <small>Link</small>
                  <p>{{ this.form.link }}</p>
                </div>
                <div v-if="this.imagePreview"><small>Image</small>
                  <img :src="imagePreview" alt="image" class="img-fluid">
                </div>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <div class="col-12 text-center">
              <button type="button" class="btn btn-primary btn-sm"
                      :disabled="this.loadingBtn"
                      @click.prevent="saveUpdatedItem(form.uuid)">
                <div v-if="this.loadingBtn" class="spinner-border spinner-border-sm text-white"></div>
                Save
              </button>
              <button type="button" class="btn btn-link" data-dismiss="modal" @click="cancelEdit">Cancel
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!--    edit item modal-->
  </div>
</template>

<script>
import IdeaBoardItem from "./IdeaBoardItem";
import IdeaBoardNewItem from "./IdeaBoardNewItem";

export default {
  name: "IdeaBoardDetails",
  props: ['board'],
  components: {
    IdeaBoardItem,
    IdeaBoardNewItem,
  },
  data() {
    return {
      loadingBtn: false,
      errors: [],
      form: new Form({
        uuid:null,
        name: null,
        description: null,
        image: '',
        link: null,
        status: 1,
      }),
      uuid: '',
      selectedFile: null,
      imagePreview: null,
      url: '/users/ideaboard/api/v1/item/',
    }
  },
  computed: {
    fb_share: function () {
      return 'https://www.facebook.com/sharer.php?u=' + this.board.share_url;
    },
    tweeter_share: function () {
      return 'https://twitter.com/intent/tweet?url=' + this.board.share_url;

    },
    pinterest_share: function () {
      return 'https://pinterest.com/pin/create/link/?url=' + this.board.share_url;
    }

  },
  methods: {
    editElement(index) {
      this.readData(index)
    },
    onFileSelected(event) {
      const image = event.target.files[0];
      this.selectedFile = image;
      const reader = new FileReader();
      reader.readAsDataURL(image);
      reader.onload = e => {
        this.imagePreview = e.target.result
      }
    },
    saveUpdatedItem(index) {
      const fd = new FormData();
      fd.append('image', this.selectedFile);
      fd.append('name', this.form.name);
      fd.append('description', this.form.description);
      fd.append('link', this.form.link);
      fd.append('status', this.form.status);
      axios.put('/users/ideaboard/api/v1/item/'+index, fd)
          .then(response => {
            console.log(response);
          })
          .catch(error => {
            console.log(error);
          });
    },
    readData(index) {
      axios.get(this.url + index)
          .then(response => {
            this.form.uuid = response.data.data.uuid;
            this.form.name = response.data.data.name;
            this.form.description = response.data.data.description;
            this.form.link = response.data.data.link;
            this.imagePreview = response.data.data.image_path;
            //this.form.image = response.data.data.image_path;
            $('#edit-item').modal('show');
          }).catch(error => {
        this.$notify({
          type: 'error',
          group: 'users',
          title: 'Error',
          text: error.response.data.message
        });
      });
    },
    cancelEdit() {
      $('#edit-item').modal('hide');
      this.form.name = null;
      this.form.description = null;
      this.imagePreview = null;
      this.form.link = null;
      this.form.status = 0;
    },
    updateBoard(value) {
      this.$emit('newItem', value);
    },
    removeElementAlert(i, id) {
      Swal.fire({
        title: 'Are you sure?',
        text: "You won't be able to revert this!",
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Yes, delete it!'
      }).then((result) => {
        if (result.value) {
          this.removeElement(i, id)
        }
      })
    },
    removeElement(i, id) {
      axios.post('/users/ideaboard/api/v1/item/' + i, {_method: 'DELETE'})
          .then(res => {
            this.$emit('deletedItem', id);
            this.$notify({
              type: res.data.data.type,
              group: 'users',
              title: res.data.data.title,
              text: res.data.data.message
            });
          })
          .catch(e => {
            console.log(e)
          });
    },
  }
}
</script>

<style scoped>

</style>

for update i am using 'saveUpdatedItem' method, as you can see i am using there formData because i need upload also however my data is empty. Hwever when i don`t use formData - just pass my fields as object everything works well. But i need also update image which user will choose. Btw code between '' i am use for display current data.

Many thanks.

0 likes
0 replies

Please or to participate in this conversation.