2
votes

Comment télécharger un fichier avec le composant vue et le contrôleur laravel [Axios]

Je souhaite télécharger un fichier image avec le composant vue sur le contrôleur laravel. Mon problème se produit lorsque je clique sur soumettre le nom / la description / l'adresse du bouton est enregistré mais que le nom de l'image n'est pas enregistré

Je veux enregistrer le nom de l'image dans ma base de données mais si ($ request-> hasFile ('id_image')) retourne toujours false

Pouvez-vous me parler de la syntaxe pour résoudre cette solution?

c'est create.vue

$listorg=new ListOrg();
$listorg->name_org=$request->get('name_org');
$listorg->description=$request->get('description');
$listorg->address=$request->get('address');
if($request->hasFile('name_image')){
    $listorg->picture= $request->image->store('images');
}
$listorg->save();
return response()->json($listorg);

dans l'exportation par défaut

data() {
    return {
      org: {
        name_org: "",
        description: "",
        address: "",
        image: ""
      }
    };
  },
  methods: {
    addNewOrg() {
      axios
        .post("/api/listorgs", this.org)
        .then(response => {
          console.log(response.data);
          if (response.data.etat) {
            this.org = {
              name_org: response.data.etat.name_org,
              description: response.data.etat.description,
              address: response.data.etat.address,
              picture: response.data.etat.image
            };
          }
        })
        .catch(error => {
          console.log("errors: ", error);
        });
        console.log(this.image);
    },
    onFileChange(e) {
      let files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      this.createImage(files[0]);
    },
    createImage(file) {
      let reader = new FileReader();
      reader.onload = e => {
        this.org.image = e.target.result;
      };
      reader.readAsDataURL(file);
    }
  }

Ceci est mon contrôleur

       <form action="/listorgs" enctype="multipart/form-data">
          <div class="form-group">
            <label>name_org:</label>
            <input type="text" class="form-control" v-model="org.name_org">
          </div>
          <div class="form-group">
            <label>picture:</label>
            <input
              type="file"
              @change="onFileChange"
              name="name_image"
              id="id_image"
              class="inputFile"
            >
          </div>
          <div class="form-group">
            <label>description:</label>
            <textarea
              class="form-control mb-2"
              rows="5"
              v-model="org.description"
            ></textarea>
          </div>
          <div class="form-group">
            <label>address:</label>
            <input type="text" class="form-control" v-model="org.address">
          </div>
          <div class="form-group">
            <button class="btn btn-primary" v-on:click="addNewOrg()">Save</button>
          </div>
        </form>

Il dit entrez la description de l'image ici


2 commentaires

vous devrez ajouter enctype = "multipart / form-data" à votre attribut

pour les téléchargements de fichiers


Je l'ai déjà essayé mais ça ne marche pas. Mais je pense qu'il est important de mettre à jour dans le code


3 Réponses :


0
votes

Votre javascript fait référence à un champ "image" et votre champ est nommé "id_image"?

Désolée, je ne peux pas encore commenter (score), mais essayez peut-être de m'en tenir à une convention quelconque?

Essayez de simplement vider et supprimer la requête complète dans votre méthode de contrôleur.

Pourrait vous donner une bonne idée de ce qui ne va pas.


2 commentaires

dans le contrôleur, j'essaye dd ($ request-> all ()); mais ça ne me montre rien.


Désolé, vue ne vous permet pas de faire dd depuis le contrôleur (je ne pense pas), mon mauvais. Essayez de mettre {{var_dump ($ request)}} dans votre modèle et transmettez les données de requête du contrôleur.



0
votes

Vous confondez 3 méthodes différentes de FORM POST. Permettez-moi de clarifier:

  1. Si vous souhaitez utiliser axios, modifiez votre formulaire et supprimez action et enctype pour éviter toute confusion que vous faites un AJAX POST et non un normal FORMULAIRE POST.

  2. Déterminez si vous essayez de récupérer le fichier au format encodé en base64 ou au format binaire. Il semble que vous vouliez créer un binaire, alors débarrassez-vous de ce code redondant base64. Et liez l'entrée du fichier directement avec v-model.

  3. OK donc maintenant que nous sommes clairs que vous voulez faire du binaire parce que votre code côté serveur a ce $ request-> hasFile ('name_image') , vous devrez soumettre comme objet FormData.

Donc, votre code ressemblerait à ceci:

$listorg=new ListOrg();
$listorg->name_org=$request->get('name_org');
$listorg->description=$request->get('description');
$listorg->address=$request->get('address');

/* you're submitting it as image with ajax
 not a regular form post so you don't want 
to use the name of the input.  That's why 
I removed the input name in the html 
above to avoid confusion */

if($request->hasFile('image')){
    $listorg->picture= $request->image->store('images');
}
$listorg->save();
return response()->json($listorg);
data() {
    return {
      org: {
        name_org: "",
        description: "",
        address: "",
        image: null
      }
    };
  },
  methods: {
    addNewOrg() {
      // point #2, to do binary data upload 
      // you need to use FormData
      var fd = new FormData();
      for (var key in this.org) {
        fd.append(key, this.org[key]);
      }

      axios
        .post("/api/listorgs", fd)
        .then(response => {
          console.log(response.data);
          if (response.data.etat) {
            this.org = {
              name_org: response.data.etat.name_org,
              description: response.data.etat.description,
              address: response.data.etat.address,
              picture: response.data.etat.image
            };
          }
        })
        .catch(error => {
          console.log("errors: ", error);
        });
        console.log(this.image);
    }

/* Since you're doing binary submit, you don't need 
all that base64 image data url codes, unless you 
want to do something else like preview image 
canvas before upload or something 
similar. */

Et puis votre code côté serveur: p >

<!-- point #1, we made it clear that it is an AJAX submit 
by handling the submit event. -->
     <form @submit.prevent="addNewOrg">
          <div class="form-group">
            <label>name_org:</label>
            <input type="text" class="form-control" v-model="org.name_org">
          </div>
          <div class="form-group">
            <label>picture:</label>
<!-- remove change event handling and bind 
the file directly to the image property -->
            <input
              type="file"
              v-model="org.image"
              class="inputFile"
            >
          </div>
          <div class="form-group">
            <label>description:</label>
            <textarea
              class="form-control mb-2"
              rows="5"
              v-model="org.description"
            ></textarea>
          </div>
          <div class="form-group">
            <label>address:</label>
            <input type="text" class="form-control" v-model="org.address">
          </div>
          <div class="form-group">
<!-- point #1, change the button type to submit button.  
The form and submit button combination also has a 
side-affect/benefit of auto-submit if user hit 
the enter button on the form. -->
            <button class="btn btn-primary" type="submit">Save</button>
          </div>
        </form>


0 commentaires

0
votes

$ listorg-> image.

Si j'ai raison, les données renvoyées par le contrôleur n'ont pas de propriété d'image. essayez console.log (this.picture);


0 commentaires