Can not send file to the .net core API from Axios (vue-nuxt) - .net-core

I get back 500 errors if i try to send a file from Vue to my API endpoint in .net Core
I followed tutorials who do this, but they do not seem to work for this setup.
.net core API:
[Route("api/[controller]")]
[ApiController]
public class FileUploadController : ControllerBase
{
[HttpPost("[Action]")]
public string sendFiles([FromBody]FileUploadAPI file)
{
return "Yes!";
}
public class FileUploadAPI
{
public IFormFile File { get; set; }
}
}
Vue:
this.$axios.post(
'https://localhost:44352/api/fileupload/sendFiles',
event.target.files[0],
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
I want to receive my file in the API
Request failed with status code 500

You would get a 404 error because you're using the wrong URL.
Your action name is sendFiles (plural) so the correct URL path would be /api/FileUpload/sendFiles.
Axios is capable of handling FormData correctly as a multipart/form-data request. You do not need to set headers (which were incorrect anyway), nor should you wrap the data in an object.
let data = new FormData();
data.append('file', files[0]); // assuming "files" refers to a FileList
this.$axios.post('https://localhost:44352/api/FileUpload/sendFiles', data)
.then(...)

Following example code snippet may be help for you. In it I am using vuetify, vue-upload-component and axios to upload an image.
<template lang="html">
<div class="imageUploader">
<!-- <v-card> -->
<!-- <div v-show="$refs.upload && $refs.upload.dropActive" class="drop-active"></div> -->
<div class="avatar-upload">
<div class="text-center p-2">
<div class="avatar-container">
<div class="no-image" v-if="files.length === 0 && file == ''">
<v-icon>cloud_upload</v-icon>
</div>
<template v-else>
<img :src="file" alt="">
</template>
</div>
</div>
<div class="text-center p-2">
<v-btn class="browse-btn" flat>
<file-upload
extensions="gif,jpg,jpeg,png,webp"
accept="image/png,image/gif,image/jpeg,image/webp"
name="avatar"
v-model="files"
#input="uploadImage"
ref="upload">
Choose File
</file-upload>
</v-btn>
</div>
</div>
<!-- </v-card> -->
</div>
</template>
<script>
import Cropper from 'cropperjs'
import VueUploadComponent from 'vue-upload-component'
//import axios from 'axios'
export default {
components: {
'file-upload': VueUploadComponent
},
props: ['order', 'imageURL'],
data() {
return {
dialog: false,
files: [],
edit: false,
cropper: false,
file: '',
}
},
mounted() {
if (this.imageURL) {
this.file = this.$baseURL+'document/downloadimage/' + this.imageURL
}
},
watch: {
imageURL() {
if (this.imageURL) {
this.file = this.$baseURL+'document/downloadimage/' + this.imageURL
}
},
},
methods: {
**uploadImage(file) {
let formData = new FormData();
formData.append('file', file[0].file);
axios.post(axios.defaults.baseURL + 'document/uploadimage', formData, {headers: {'Content-Type': 'multipart/form-data'}})
.then((response) => {
this.dialog = false
this.$emit('upload', {id: response.data.result[0].objectId, order: this.order})
this.file = this.$baseURL+'document/downloadimage/' + response.data.result[0].objectId
let reader = new FileReader()
reader.readAsDataURL(file[0].file)
reader.onload = () => {
let base64 = reader.result.split(',')[1]
this.$emit('base64', base64)
}
this.getDimensions(this.$baseURL+'document/downloadimage/' + response.data.result[0].objectId, (result) => {
this.$emit('dimensions', {width: result.width, height: result.height})
})
})
.catch((error) => {
console.log(error)
})
},**
getDimensions(url, callback) {
var img = new Image();
img.src = url
img.onload = function() {
var result = {width: this.width, height: this.height}
callback(result)
}
}
},
}
</script>

Related

I am trying to get driver related to vehicle using vue js

I have shown vechicle data just I want to get driver data related to vehicle but unfortuntly i am getting error undefined please help me how can i show into draggablelist thank u ?
Controller
public function index(){
return $vehicles = Vehicle::with('driver')->get();
}
template view
<div class="row">
<div class="col-6">
<q-card-section>
<div class="tw-grid">
<div class="tw-col-span-6">
<DraggableList
v-model="api.drivers"
label-key="username"
:colors="colors"
/>
</div>
</div>
</q-card-section>
</div>
</div>
vue js
export default {
data () {
return {
api: {
vehicles: [],
drivers: []
}
}
},
mounted () {
this.fetchVehiclesDriver()
},
methods: {
fetchVehiclesDriver () {
this.$api.get(this.apiRoute('client.vector.driver', {
}))
.then(({ data }) => {
this.api.vehicles = data.vehicles
this.api.drivers = data.vehicles.driver
console.log(data.vehicles.driver) // undefined
})
}
}
}

How to use a method inside v-if

I'm trying to display countries from database which the continentId foreach country == logged user scope.
An user scope is between 1-5.
here is my vue template
<div class="container w-75" v-show="showGrid">
<div class="row" style="width:900px; height:900px; padding-left:200px">
<div class="col-md-4" v-for="country of countries" v-bind:key="country">
<div v-if="country.continentId==setup" class="card p-3" style="cursor:pointer">
<router-link :to="{ path: '/FetchData', query: { query: country.countryName}}">
<div class="d-flex flex-row mb-3">
<div class="d-flex flex-column ml-2"><span>{{country.countryId}}</span></div>
</div>
<h6 style="text-align:left">{{country.countryName}}</h6>
</router-link>
</div>
and those are my methods
export default {
methods: {
async getCountries() {
let country = this.$route.query.query
if (!country) {
await axios
.get("https://localhost:44391/api/Pho/GetCountries")
.then((res) => (this.countries = res.data))
} else {
await axios
.get(
"https://localhost:44391/api/Pho/GetCountries?country=" +
this.$route.query.query
)
.then((res) => (this.countries = res.data))
this.searchbar = false
}
},
async setup() {
let token = "??"
const scope = ref("")
const response = await fetch(
"https://localhost:44391/api/Auth/UserScope",
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
credentials: "include",
}
)
const content = response.json()
scope.value = `${content.scope}`
return {
scope,
}
},
},
async mounted() {
this.setup()
await this.getCountries()
},
}
the method setup return le scope of the logged user and the getCountries method returns the list of countries.
when i inspect i find that the scope is returned but the <div v-if="country.continentId==setup" class="card p-3" style="cursor:pointer"> condition does not work properly.
The setup() hook is not supposed to be under methods. It needs to be at the top level of the object:
export default {
methods: {
// setup() { /*...*/ } ❌
},
setup() { /*...*/ }, ✅
}
Also, don't make the setup() hook async unless you're intentionally making it an async component, which requires a <Suspense> as an ancestor. Instead, move the asynchronous code into its own function within:
export default {
setup() {
const scope = ref('')
const fetchUserScope = async () => {
const response = await fetch(/*...*/)
const content = await response.json()
scope.value = content.scope
}
fetchUserScope()
return { scope }
}
}
Also, you can't invoke the setup() hook from the template like that. You're really just trying to compare continentId to the scope value, so use scope directly:
<!-- <div v-if="country.continentId == setup"> --> ❌
<div v-if="country.continentId == scope"> ✅
You shouldn't try to invoke setup() from mounted() hook either. Vue controls the lifecycle hooks itself:
export default {
mounted() {
// this.setup() ❌
}
}

Card element with favoris cannot trigger API call

I am really lost with Nextjs. I seem to have understood that I need to use swr but I am not sure that it will work in my case. or even how to make it work.
I have products which have the same component in several pages in my site. On this component, I have a favorites button which must be triggered on all these pages. on click, it must make a POST or DELETE, with a token and the product id.
My component looks like this for the moment and of course, postFavorites and deleteFavoris don't work:
import React, { useEffect, useState } from "react"
import Link from 'next/link'
import Styles from "./card.module.scss"
import axios from 'axios'
export default function Card(props) {
const [favoris, setFavoris] = useState(false);
const deleteFavoris = async () => {
console.log("click");
try {
const res = await axios({
method: 'POST',
url: `${process.env.NEXT_PUBLIC_BASE_API}/favorites`,
headers: {
Authorization: "Bearer " + session.token,
},
body: {
advert: props["#id"]
}
});
} catch (error) {
if (error.response) {
throw new Error(await error.response.data.message)
}
}
}
const postFavoris = async () => {
console.log("click");
try {
const res = await axios({
method: 'DELETE',
url: `${process.env.NEXT_PUBLIC_BASE_API}/favorites`,
headers: {
Authorization: "Bearer " + session.token,
},
body: {
advert: props["#id"]
}
});
} catch (error) {
if (error.response) {
throw new Error(await error.response.data.message)
}
}
}
const handleClick = () => {
if (favoris === true) {
deleteFavoris()
} else {
postFavoris()
}
setFavoris(!favoris)
}
return (
<div className={Styles.card}>
<Link href={"/annonce?id="+props.id} passHref>
<a className={Styles.imageCard} style={{backgroundImage: `url(${props.imageSrc})`}}>
<p className={Styles.localisationCard}><span className="material-icons">location_on</span>{props.localisation}</p>
</a>
</Link>
<div className={Styles.favCard + " " + ((favoris === true) && Styles.active)} onClick={() => handleClick()}></div>
<p className={Styles.titleCard}>{props.title}</p>
<p className={Styles.pricesCard}><span className="material-icons-outlined">local_offer</span>Prix : {props.prices}</p>
<p className={Styles.eligibilitesCard}><span className="material-icons-outlined">check_circle</span>Eligibilité ({props.eligibilities})</p>
</div>
)
}

Need help in my VueJS + VueX + Firebase project

I am trying to show the current userName and title which was already created by signin and now stored in Firebase Cloud Firestore database.
But I don't know how to handle this, I can't find an error in the code by my self.
Here is the code:
<template>
<div id="dashboard">
<section>
<div class="col1">
<div class="profile">
<h5>{{ userProfile.name }}</h5>
<p>{{ userProfile.title }}</p>
<div class="create-post">
<p>create a post</p>
<form #submit.prevent>
<textarea v-model.trim="post.content"></textarea>
<button #click="createPost"
class="button">post</button>
</form>
</div>
</div>
</div>
<div class="col2">
<div>
<p class="no-results">There are currently no posts</p>
</div>
</div>
</section>
</div>
</template>
<script>
const fb = require('../firebaseConfig.js')
import { mapState } from 'vuex'
import firebase from 'firebase'
const db = firebase.firestore()
export default {
data() {
return {
post: {
content: ''
}
}
},
computed: {
...mapState(['userProfile'])
},
methods: {
createPost() {
fb.postsCollection.add({
createdOn: new Date(),
content: this.post.content,
userId: this.currentUser.uid,
userName: this.userProfile.name,
comments: 0,
likes: 0
}).then(ref => {
this.post.content = ''
}).catch(err => {
console.log(err)
})
}
}
}
</script>
Store.js
import Vue from 'vue'
import Vuex from 'vuex'
const fb = require('./firebaseConfig.js')
Vue.use(Vuex)
// handle page reload
fb.auth.onAuthStateChanged(user => {
if (user) {
store.commit('setCurrentUser', user)
store.dispatch('fetchUserProfile')
}
})
export const store = new Vuex.Store({
state: {
currentUser: null,
userProfile: {}
},
actions: {
clearData ({ commit }) {
commit('setCurrentUser', null)
commit('setUserProfile', {})
},
fetchUserProfile ({
commit,
state
}) {
fb.usersCollection.doc(state.currentUser.uid).get().then(res => {
commit('setUserProfile', state.res.data())
}).catch(err => {
console.log(err)
})
console.log(state)
}
},
mutations: {
setCurrentUser (state, val) {
state.currentUser = val
},
setUserProfile (state, val) {
state.userProfile = val
}
}
})
Error output:
userProfile output as Object:

WordPress REST API not working when filtering by slug using Axios

I was able to display WordPress post content using axios and Vue.js. Once I switched to filtering by slug, I was unable to display post content.
<template>
<div>
<article>
<h2 class="subtitle">{{ post.title.rendered }}</h2>
<div v-html="post.excerpt.rendered"></div>
</article>
</div>
</template>
<script>
import axios from "axios";
import Router from 'vue-router'
export default {
name: 'ShowPost',
data () {
return {
post: []
}
},
created() {
this.slug = this.$route.params.slug;
},
mounted() {
axios({ method: "GET", "url": "https://wpdemo.stevensoehl.com/wp-json/wp/v2/posts?slug=" + this.slug }).then(json => {
this.post = json.data;
}, error => {
console.error(error);
});
}
}
</script>
It is necessary to check whether there is cross domain problem in the console, and there may be no cross domain problem
I figured it out a solution. In my links to an individual post I carried over the slug and id as params
<router-link :to="{name: 'ShowPost', params: {slug: post.slug, id:post.id}}">{{ post.title.rendered }}</router-link>
Route is slug and filter response by id. It now works as planned.
import axios from "axios";
export default {
name: 'ShowPost',
data () {
return {
post: []
}
},
created() {
this.id = this.$route.params.id;
},
mounted() {
axios({ method: "GET", "url": "https://wpdemo.stevensoehl.com/wp-json/wp/v2/posts/" + this.id }).then(json => {
this.post = json.data;
}, error => {
console.error(error);
});
}
}

Resources