multer : req.file is undefined - vue.js

I want to send a file with axios, from my Vue.js to my Node.js,
but the req.file parameter is never filled, it's undefined
Here is the simplified code from my vue :
Inscription.vue :
<template>
<div class="main_content">
<h1>Inscription</h1>
<div><input type='file' #change='openFile'></div>
<button type='button' v-on:click="inscription" class="inscription">Inscription</button>
</div>
</template>
<script>
import Axios from 'axios';
export default {
data () {
return { selectedFile: null}
},
methods:{
openFile (event) {
this.selectedFile = event.target.files[0];
},
inscription () {
let fd = new FormData();
fd.append('avatarBase64', this.selectedFile);
Axios.create({baseURL: 'http://localhost:4444'}).post('/api/testUploadImage', {avatarBase64: fd});
}
}
My simplified node.js application :
main.ts
import express from "express";
var cors = require('cors');
var bodyParser = require('body-parser')
const multer = require('multer')
const http = require('http');
const server = express();
server.use(cors({origin: true}))
server.use(bodyParser.json({limit: '50mb', extended: true}));
server.use(
bodyParser.urlencoded({
extended: true
})
)
server.post("/api/testUploadImage", upload.single('avatarBase64'), async (req: any, res: any) => {
// req.file is undefined PROBLEM THERE
});
const httpServer = http.createServer(server);
httpServer.listen(port);

try changing headers of axios with
'content-type': 'multipart/form-data'

I found out : i was sending this
Axios.create({baseURL: 'http://localhost:4444'}).post('/api/testUploadImage', {avatarBase64: fd});
instead of this :
Axios.create({baseURL: 'http://localhost:4444'}).post('/api/testUploadImage', fd);

change your multer version and try it agian
npm i multer#2.0.0-rc.2
and edit this:
Axios.create({baseURL: 'http://localhost:4444'}).post('/api/testUploadImage', fd);

Related

How to set authentications headers with Vue apollo and composition api?

I've build my app with Vite. I read many documents on web about the topic but I'm still very confused. I've a login form that send credentials to a protected view. When post the data I set the headers and store the Bearer token in the local storage.
The problem is that it doesn't work cause the Bearer token result equal to null.
Only when I logout the token is set in the headers.
That's how is the header when I log in
And here how it's set when I log out...
My main.js code is this:
import { createApp, provide, h } from "vue";
import {
ApolloClient,
createHttpLink,
InMemoryCache,
} from "#apollo/client/core";
import { DefaultApolloClient } from "#vue/apollo-composable";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import { provideApolloClient } from "#vue/apollo-composable";
const authToken = localStorage.getItem("auth-token");
const httpLink = createHttpLink({
uri: "http://localhost/graphql",
headers: {
Authorization: "Bearer " + authToken,
},
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link: httpLink,
cache,
});
provideApolloClient(apolloClient);
const app = createApp({
setup() {
provide(DefaultApolloClient, apolloClient);
},
render: () => h(App),
});
app
.use(router)
.use(createPinia())
.mount("#app");
and this is my routes.js
const router = createRouter({
history: createWebHistory(),
routes
})
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = localStorage.getItem('auth-token');
if(requiresAuth && isAuthenticated===null){
next('/auth/login');
}else {
next();
}
});
I'm surely making some mistakes in my main.js but I cannot understand what's wrong. I'm very confused :-/
Thanks to who'll be able to help me.
Try using a helper function to get the token from local storage; I'm using this method and it's working fine for me. To get your code more organized, create a separate folder to define the apollo client. Here is the code:
// apolloClient.ts
import { ApolloClient, InMemoryCache, HttpLink } from "#apollo/client/core";
function getHeaders() {
const headers: { Authorization?: string; "Content-Type"?: string } = {};
const token = localStorage.getItem("access-token");
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
headers["Content-Type"] = "application/json";
return headers;
}
// Create an http link:
const httpLink = new HttpLink({
uri: `${import.meta.env.VITE_API_URL}/graphql`,
fetch: (uri: RequestInfo, options: RequestInit) => {
options.headers = getHeaders();
return fetch(uri, options);
},
});
// Create the apollo client
export const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: httpLink,
defaultOptions: {
query: {
errorPolicy: "all",
},
mutate: {
errorPolicy: "all",
},
},
});
Then you can use it in your main.ts like this:
// main.ts
import { createApp, h } from "vue";
import { provideApolloClient } from "#vue/apollo-composable";
import App from "./App.vue";
import { apolloClient } from "./apolloClient";
const app = createApp({
setup() {
provideApolloClient(apolloClient);
},
render: () => h(App),
});
app.mount("#app");

axios base url from local json file

Tried to load baseURL for axios from local json file and export in variable "http" for use in applications. Tried to different way to implemetntation.Pls help
import axios from "axios";
const getURL = async () => {
const resp = await axios.get('/config.json');
return axios.create({
baseURL: resp.data.url,
});
};
export const http = getURL();
You could try with .env files https://cli.vuejs.org/guide/mode-and-env.html
If you're using vue-cli, then this would work for you:
Inside main.js file (this is entry point):
import axios from 'axios'
/**
* config.json implementation
*/
let axiosInstance = null
;(async () => {
try {
const config = await axios.get('/config.json')
axiosInstance = axios.create({
baseURL: config?.data?.url || 'some-fallback-url'
})
} catch (err) {
console.warn('Error!', err)
} finally {
Vue.prototype.$http = axiosInstance
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
}
})()

I cant post to localhost with axios help please?

I am trying to send data to localhost with axios post, But for some reason what ever I try, I get the same error
"not send Error: Network Error"
this is my front end code
import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {
constructor(props) {
super(props);
this.state = { }
}
sendData =()=>{
var url ="http://localhost:9000/api"
var data={
code:"hello world",
}
axios.post(url,data)
.then(res => {
console.log("data send")
})
.catch(err => {
console.log("not send"+err)
console.error(err);
})
}
render() {
return (
<div>
<form>
<input type="text" name="data"/>
</form>
{this.sendData()}
</div>
);
}
}
export default App;
and this is my back end code
var express=require('express');
var app=express();
app.use(express.json());
app.post('/api', function(req,res){
res.json(req.body);
})
app.listen(9000);
Can you post the error as well. It is most likely to be A CORS issue. If you can call the API from A Rest Client like Postman and not browser it is a CORS Issue
Install cors package npm install cors
Update your backed to allow CORS
var express = require('express')
var cors = require('cors') // New
var app = express()
app.use(cors()) // New
app.use(express.json());
app.post('/api', function(req,res){
res.json(req.body);
})
app.listen(9000);

fetch POST request is pending (sending data from registration form)

I know that similar questions have already been here, but I didn't find anything for my problem.
I am creating project using [Webpack-Express-Pug-VanillaJS] stack of technologies.
I'm trying to make POST-request to send formData to '/api/users' using fetch a push data to array in my express file, but its only pending...
What kind of problems it can be?
client-side code
document.addEventListener('DOMContentLoaded', () => {
async function postData(url, data) {
try {
console.log('addEventListener works!')
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
console.log('fetch works!')
return await response.json()
} catch(e) {
console.warn('Error',e.message)
}
}
const forms = document.getElementsByTagName('FORM');
for (let i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(e) {
console.log(forms[i])
e.preventDefault();
let formData = new FormData(this);
formData = Object.fromEntries(formData);
console.log(formData) return object like {name:'Zhanna', age:25, email:'123zhanna#gmail.com'}
postData('/api/users', formData).then(data => console.log('Successful!'))
})
}
})
server-side
const path = require('path')
const express =require('express')
const webpack = require('webpack')
const bodyParser = require('body-parser')
const users = require('../routes/userInfo')
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from '../../webpack.dev.config.js'
import { v4 } from 'uuid';
const PORT = process.env.PORT || 8080
const app = express(),
compiler = webpack(config)
app.use(users.router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.json());
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'pug');
app.locals.basedir = __dirname;
app.use('/assets',express.static(path.join(__dirname,'assets')))
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
})
)
app.use(webpackHotMiddleware(compiler))
app.get('/registration', (req,res)=> {
res.status(200).render('registration')
})
app.get('/login', (req,res)=> {
res.status(200).render('signIn')
})
app.get('/', (req, res) => {
res.status(200).render('index')
}
)
app.get('/api/users', (req,res)=> {
res.status(200).json(users.list)
})
app.post('/api/users', (req,res)=> {
const user = {...req.body, id:v4()}
users.list.push(user)
console.log('Data was sent')
res.status(201).json(user)
})
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
And in my console there is only 3 logs:
addEvent listener works!
<form class="registration--form" id="send-form">...<form>
3.{name: "Zhanna", surname: "Kaymedenova", gender: "female", brth: "07.01.1994", email: "zh.kaymed#gmail.com"}

How can I get data passed from axios post request through to nuxt serverMiddleware?

I am trying to pass some data to my serverMiddleware using axios but I can't seem to be able to get the data in my serverMiddleware
guilds page script:
<script>
export default {
async fetch() {
const token = 'testToken'
const guilds = await this.$axios.$post('/api/guilds', { token })
}
}
</script>
serverMiddleware:
import axios from 'axios'
import express from 'express'
const router = express.Router()
const app = express()
router.use((req, res, next) => {
Object.setPrototypeOf(req, app.request)
Object.setPrototypeOf(res, app.response)
req.res = res
res.req = req
next()
})
router.post('/', (req, res) => {
console.log(req)
})
export default {
path: '/api/guilds',
handler: router
}
Token should be an object of key-value.
async fetch() {
const token = 'testToken'
const guilds = await this.$axios.$post('/api/guilds', { token: token })
}
Then you can take it from req.body in serverMiddleware.