data does not arrive properly in req.body (axios post method) - node.js

data not arriving in req.body when using axios in post methord, when i testing Api using postman is Working properly,
in console payload also showing,
Pay load :-
Api Call:
axios.post('offices/office',{name,email},config)
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
});
axios instance:
import axios from 'axios'
import { BaseUrl } from './Api';
const instance = axios.create({
baseURL:BaseUrl,
});
export default instance
Server :
code : officeRouter:
const express =require('express')
const { createOffice } = require('../Controller/Office_Controller')
const router=express.Router()
router.post('/office',createOffice)
module.exports=router
controller.js
createOffice:async(req,res) => {
console.log(req.body)
},

Related

why i cant get an axios response in react?

so I'm having a problem getting data from my server to my front-end using axios.
as you can see in this picture I'm getting a response for the GET method for users/users.
this is my showUsers function
const showUsers = async (req, res) => {
await User.find({})
.then((user) => {
res.status(200).json(user);
})
.catch((error) => {
res.status(400).send(error);
});
};
this is my axios api export
import axios from "axios";
export default axios.create({
baseUrl: "http://localhost:8080/users",
});
and this is my useEffect
import api from "../api/users";
import { useState, useEffect } from "react";
export const LogIn = (props) => {
const { setIsNewMember } = props;
const [users, setUsers] = useState([]);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await api.get("/users");
setUsers(response.data);
} catch (err) {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
console.log(err.response.headers);
} else {
console.log(`Error: ${err.message}`);
}
}
};
fetchUsers();
}, []);
I'm getting this error on the frontend
so although I'm getting it from the postman and other services I'm not getting it on the front.
any idea why is that happening?

Heroku API not able to access cookies

I have hosted a JWT auth API on heroku. While accessing the API using axios from my front-end React app, I notice that the protected routes can never be fetched since they are dependent on res.cookies which are never set. While testing the API out on postman, it sets the cookies and everything works fine. Can you help me finding where I am going wrong and how I can overcome this.
Sample cookie that is supposed to be set(working fine with postman)
This cookie is needed, because when I GET /user, with the following code:
exports.checkUser = catchAsync(async (req, res, next) => {
let currentUser;
if (req.cookies.jwt) {
const token = req.cookies.jwt;
const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);
currentUser = await User.findById(decoded.id);
} else {
currentUser = null;
}
res.status(200).send({ currentUser });
});
currentUser should be populated as follows
When I access this API using my react frontend: this being my useAuth hook
import { useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import axios from "axios";
import { UserContext } from "./userContext";
export default function useAuth() {
let history = useHistory();
const { setUser } = useContext(UserContext);
const [error, setError] = useState(null);
const setUserContext = async () => {
return await axios
.get("<my api link>/user")
.then((res) => {
console.log(res);
setUser(res.data.currentUser);
history.push("/home");
})
.catch((err) => {
console.log(err);
setError(err);
});
};
const registerUser = async (data) => {
const { username, email, password, passwordConfirm, name } = data;
return axios
.post("<My api link>/auth/post", {
username,
email,
password,
passwordConfirm,
name,
})
.then(async (res) => {
console.log(res);
await setUserContext();
})
.catch((err) => {
console.log(err);
return setError(err);
});
};
res.data.currentUser is ALWAYS null. Any help is appreciated
The concept of JWT is that the handling of the token is handed over to the client.
Hence, the frontend is supposed to store/save the JWT Token it receives in cookies or localstorage and is supposed to send them via headers in requests where you want to access such protected routes.
Hence it's the frontend duty and that's why Postman handles it automatically for you.
You can use react-cookie to save and retrieve this JWT token in the frontend whenever required and you will have to reform your axios request.
In your specific case, you can do the following for GET request:
axios.get('URL', {
withCredentials: true
});
But I would strongly recommend amending your backend to extract JWT tokens from headers instead of cookies, which would make your request, something similar to:
let JWTToken = 'xxyyzz'; // Get this from cookie or localstorage, hardcoded for demonstration.
axios
.get("URL", { headers: {"Authorization" : `Bearer ${JWTToken}`} })
.then(res => {
this.profile = res.data;
console.log('Fetched Data is', res.data);
})
.catch(error => console.log(error))
Do not forget to enable CORS on your backend!

why do we need thunk.withExtraArgument?

I currently have an issue with my code so while I am debugging i am trying to understand which approach shall I take in order to solve the issue.
I am using google oauth with passport.js. from client I have an action to fetch the authentication.
import axios from "axios";
const axiosInstance = axios.create({
baseURL: "http://localhost:3000/api",
timeout: 3000,
});
export const fetchUser = () => async (dispatch, getState, api) => {
try {
await axiosInstance.get("/auth/current_user").then((res) => {
dispatch({ type: FETCH_USER, payload: res.data });
});
} catch (e) {
console.log(e.message);
}
};
here is the client-side store set up:
const store = createStore(
reducers,
window.INITIAL_STATE, //
applyMiddleware(thunk)
);
and this is the server side store set up:
export default (req) => {
const store = createStore(reducers, {}, applyMiddleware(thunk));
console.log("store from servre", store);
return store;
};
Another approach would be instead of defining axiosInstance in action, i define it when I create the client side store and pass it to thunk.withExtraArgument iike this.
const axiosInstance = axios.create({
baseURL: "/",
});
const store = createStore(
reducers,
window.INITIAL_STATE,
applyMiddleware(thunk.withExtraArgument(axiosInstance))
);
I changed the action accordingly:
export const fetchUser = () => async (dispatch, getState, api) => {
try {
await api.get("/auth/current_user").then((res) => {
dispatch({ type: FETCH_USER, payload: res.data });
});
} catch (e) {
console.log(e.message);
}
};
My question which method should I use. CUrrently I have issue in both methods :) . But if i know which way is correct then I will solely focus on that method.
Thank You
I will suggest you go with with creating an instance of axios in a file and importing it whereever you need it, instead of adding it as an argument to thunk
api.js
import axios from "axios";
const axiosInstance = axios.create({
baseURL: "http://localhost:3000/api",
timeout: 3000,
});
export default axiosInstance;
actions.js
import api from '/path/to/api';
export const fetchUser = () => async (dispatch, getState) => {
try {
await api.get("/auth/current_user").then((res) => {
dispatch({ type: FETCH_USER, payload: res.data });
});
} catch (e) {
console.log(e.message);
}
};
The advantage of the above solution is that you can import and use the instance for making direct API calls too in your components for which you do not need to dispatch actions to the reducers.

ctx request body is undefined with nodejs

I have a problem, when I post my form, i can't get what is in my post in my API.
this is my post with axios in react :
onSubmit = () => {
let data = {
nickname: this.state.nickname,
password: this.state.password
}
axios.post("/api/user/login", { data })
.then(res => {
console.log("res from api is => ", res.data);
})
}
and this is in my API :
import koaBody from "koa-body";
const app = new koa();
const router = new Router();
app.use(router.routes());
app.use(koaBody());
router.post("/api/user/login", async(ctx) => {
console.log("body is => ", ctx.request.body);
ctx.body = "ok";
});
the problem is ctx.request.body is always undefined...
Can you tell me why ?
I tried with router.get and I have no problem, it works fine.
You need to load the body parser before the router, otherwise the router will get to handle the requests before the body contents are parsed:
app.use(koaBody());
app.use(router.routes());

Send response from server side axios request to React/Redux app

I'm a little new to creating a backend in Node/Express, but I am trying use axios to make HTTP requests. I've set up express routes that will make the necessary request and I know from using Postman that GET request I'm testing does return a response. Where I'm stuck is how to return that data and send it to my React/Redux app to use.
-Server Side-
//Express Route
app.get('/api/recipes', recipeController.getRecipes)
//Controller Function that makes axios request
const axios = require('axios')
const Promise = require('bluebird')
module.exports = {
getRecipes(req, res) {
const url = "https://gw.hellofresh.com/api/recipes/search?country=us&limit=9"
const token = "IUzI1NiIsInR5c"
axios
.get(url, {
"headers": {"Authorization": "Bearer " + token}
})
.then((response) => {
console.log(response)
})
.catch((err) => {
console.log(err)
})
}
}
-Client Side-
I dispatch the following action and make a call using the endpoint I created. However, at this point, I'd get an error status even though on the server side I was able to get a response. I tried playing around using Promises as I read that axios GET requests returns promises, but couldn't wrap my head around on how to implement it.
export const getRecipes = () => {
return (dispatch) => {
axios
.get('/api/recipes')
.then((resp) => {
console.log(resp)
})
.catch((err) => {
console.log(err)
})
}
}
You need to call res.send in the route, to send the data to the client:
module.exports = {
getRecipes(req, res) {
const url = "https://gw.hellofresh.com/api/recipes/search?country=us&limit=9"
const token = "IUzI1NiIsInR5c"
axios
.get(url, {
"headers": {"Authorization": "Bearer " + token}
})
.then(response => {
console.log(response)
res.send(response) // <= send data to the client
})
.catch(err => {
console.log(err)
res.send({ err }) // <= send error
})
}
}

Resources