I want to upload my data with an image. I've searching for similar case but I've found help only for data or only for upload but never the two together.
The form is between line 3 - 36 and I call enregistreAjout method
Datas like title, category are added to strapi but not the picture.
Im using strapi 3 and vuejs 2
What am i doing wrong ?
<template>
<div>
<!-- ############# AJOUTER / MODIFIER ############# -->
<!-- Si boutonAjouMod est true on affiche le bouton Ajouter -->
<div class="btn btn-outline-primary" v-if="boutonAjouMod" v-on:click="toggleAfficheAjouter">{{boutonAjouter}}</div><!-- je clique on lance la méthode toggleafficheAjouMod -->
<!-- Si afficheAjouMod est true on affiche le formulaire d'ajout -->
<form action="" class="mt-4" v-if="afficheAjouMod">
<div class="form-group">
<label for="title">Titre</label>
<input v-model="titre" type="text" name="title" class="form-control" required />
</div>
<div class="form-group">
<label for="category">Catégorie</label>
<select v-model="categorie" class="form-control" required>
<option selected>----</option>
<option value="job">maison</option>
<option value="rent">appartement</option>
</select>
</div>
<div class="form-group">
<label for="content">Commentaire</label>
<textarea v-model="commentaire" cols="30" rows="10" class="form-control" required></textarea>
</div>
<div class="form-group">
<label for="picture">Image</label>
<!-- v-model ne fonctionne pas il faut utiliser v-on:change -->
<input type="file" id="file" name="picture" ref="file" class="form-control" v-on:change="handleFileUpload()"/>
<br><img src="../../assets/default.jpg" alt=""><br>
</div>
<input type="hidden">
<button type="submit" class="btn btn-xs btn-primary" v-on:click="enregistreAjout">Enregistrer</button>
<!--<div class="btn btn-xs btn-primary" v-on:click="enregistreAjout">Enregistrer</div>-->
<div class="btn btn-xs" v-on:click="toggleAfficheAjouter">Annuler</div>
</form>
<!-- ############# VOIR ############# -->
<!-- Si afficheVue est true on affiche la vue -->
<div v-if="afficheVue">
<h3>{{titre}}</h3>
<br>
<label for="category">Type : {{categorie}}</label>
<br>
<label for="content">{{commentaire}}</label>
<br>
<label for="picture"><img v-bind:src="completeImgUrl(image)" v-bind:alt="titre"/></label>
<br>
<div class="btn btn-xs btn-primary mt-2" v-on:click="toogleAfficheView">Retour</div>
</div>
<!-- ############# TABLEAU ############# -->
<!-- Si afficheTableau est true on affiche le tableau -->
<div v-if="afficheTableau">
<h1 class="text-center">Annonces</h1>
<!--barre de recherche-->
<input type="search" class="form-control" placeholder="Rechercher par titre" />
<!-- Affichage du tableau -->
<table class="table table-bordered">
<thead class="thead-light">
<tr>
<th scope="col">Titre</th>
<th scope="col">Catégorie</th>
<th scope="col">Commentaire</th>
<th scope="col">Image</th>
</tr>
</thead>
<tbody>
<!-- Debut affichage tableau dynamique -->
<tr v-bind:key="index" v-for="(annonce,index) in toutesLesAnnonces" > <!-- Index obligatoire pour boucle for -->
<td>{{annonce.title}}</td>
<td>{{annonce.category}}</td>
<td>{{annonce.content}}</td>
<td>
<img v-bind:src="completeImgUrl(annonce.picture.formats.thumbnail.url)" v-bind:alt="annonce.title"/>
</td>
<td>
<div class="btn btn-sm btn-outline-success mt-5 ms-3 me-2" v-bind:value=annonce.id>Modifier</div>
<div class="btn btn-sm btn-outline-primary mt-5 me-2" v-on:click="toogleAfficheView(annonce.id)" v-bind:value=annonce.id>Voir</div>
<div class="btn btn-sm btn-outline-danger mt-5" v-bind:value=annonce.id>Supprimer</div>
</td>
</tr>
<!-- Fin affichage tableau dynamique -->
</tbody>
</table>
</div>
</div>
</template>
Scripts
<script>
//valeurs globales
import constantes from'../global/constantes'
//appel d'une fonction globale
import {getWithExpiry} from '../global/Fonctions.js'
//gestion des API
import axios from 'axios'
export default {
name: 'AccueilDisplay',
data() {
return {
//token jwt
token: '',
//variables Cacher/Voir les balises
boutonAjouMod: true,
afficheAjouMod: false,
afficheVue: false,
afficheTableau: true,
boutonAjouter: 'Ajouter une annonce',
toutesLesAnnonces: [],
//upload image
file: null,
//isImage: false,
//previewImage = '',
//Voir / Ajouter
titre: '',
categorie: '',
commentaire: '',
image: ''
}
},
methods: {
toggleAfficheAjouter: function(){ //affiche / cache Ajouter
this.afficheAjouMod=!this.afficheAjouMod //est égale au contraire de la valeur précente
this.afficheTableau=!this.afficheTableau
},
completeImgUrl: function(ImgLink){ //sert à ajouter l'url complete pour l'image
return constantes.serveurapi + ImgLink
},
handleFileUpload: function(){ // recuperation de l'image
this.file = this.$refs.file.files[0]
//console.log(this.file)
/*
if (
this.file.name.includes(".png") ||
this.file.name.includes(".jpg")
) {
this.isImage = true;
this.previewImage = URL.createObjectURL(this.file);
} else {
this.isImage = false;
}
*/
},
/*enregistreAjout: function(){
//console.log(this.token)
},*/
async enregistreAjout() {
try {
await axios.post(`${constantes.serveurapi}/${constantes.collectionAnnonces}`, {
title: this.titre,
category: this.categorie,
content: this.commentaire
}, {
headers : {
'content-type': 'application/json',
'Authorization': 'Bearer ' + this.token
}
})
.then((envoiData) => {
console.log("envoiData",envoiData)
console.log("files",this.file)
const formData = new FormData();
formData.append("files",this.file)
formData.append("ref","annonce")
formData.append("refId",envoiData.id)// quel est l'id
formData.append("field","file")//quel est le champ
console.log("formData",formData)
axios.post(`${constantes.serveurapi}/upload`, {
body: formData
},{
headers : {
'content-type': 'application/json',
'Authorization': 'Bearer ' + this.token
}
})
})
} catch(e) {
this.error = true
}
},
toogleAfficheView: function(id){ // affiche / cache Vue
this.afficheTableau=!this.afficheTableau
this.afficheVue=!this.afficheVue
if (!this.afficheTableau) { // si on desactive le tableau alors on affiche la vue
this.boutonAjouMod = !this.boutonAjouMod // on vire le boutron ajouter
const chercheObjet = this.toutesLesAnnonces.find(element => element.id === id) //on recherche l'objet par son id
this.titre = chercheObjet['title']
this.categorie = chercheObjet['category']
this.commentaire = chercheObjet['content']
this.image = chercheObjet['picture']['formats']['thumbnail']['url']
} else {
this.boutonAjouMod = !this.boutonAjouMod //sinon on affiche le tableau et on remet le bouton ajouter
this.titre = '' //on remet à vide
this.categorie = ''
this.commentaire = ''
this.image = ''
}
}
},
created() { // partie affichage du tableau lors création de l'affichage
const getuser = getWithExpiry("user")
this.token = JSON.parse(getuser).jwt
axios.get(`${constantes.serveurapi}/${constantes.collectionAnnonces}` , {
headers : {
'content-type': 'application/json',
'Authorization': 'Bearer ' + this.token
}
})
.then(reponse => {
//console.log(reponse.data)
for (const annonce of reponse.data) {
this.toutesLesAnnonces.push(annonce)
}
})
.catch(err=>{
console.log(err)
})
}
}
</script>
So far I've tried this :
async enregistreAjout() {
try {
await axios.post(`${constantes.serveurapi}/${constantes.collectionAnnonces}`, {
title: this.titre,
category: this.categorie,
content: this.commentaire
}, {
headers : {
'content-type': 'application/json',
'Authorization': 'Bearer ' + this.token
}
})
.then((response) => {
console.log("response",response)
console.log("files",this.file)
const formData = new FormData();
formData.append("files",this.file)
formData.append("ref","annonce")
formData.append("refId",response.data.id)// quel est l'id
formData.append("field","picture")//quel est le champ
console.log("formData",formData)
return axios.post(`${constantes.serveurapi}/upload`, {
body: formData,
},{
headers : {
'Authorization': 'Bearer ' + this.token
}
})
})
} catch(error) {
console.log(error)
}
}
And I get an error 400 bad request. It's really hard to resolve this.