Can't destructure data from axios post request response - javascript

So I'm making a simple CRUD app trying to familiarize myself with redux. Basically I'm transferring data from a form and sending a post request to the server to create a new blog post (more or less). Here's the code for the onSubmit:
const handleSubmit = (e) => {
e.preventDefault()
dispatch(createPost(postData));
}
Here's the action being dispatched and where the error is coming from (src/actions/posts.js):
export const createPost = (post) => async (dispatch) => {
try
{
const { data } = await api.createPost(post);
dispatch({ type: "CREATE", payload: data});
}
catch (error)
{
console.log(error.message);
}
}
This function isn't able to destructure data from the api's response, because the response is undefined. Here's the code that sends the request from src/api/index.js:
export const createPost = (newPost) => {
axios.post(url, newPost);
}
When I console.log the response from this function using .then(), it returns a 201 along with exactly what one would expect from a successful request. So the response returns 201 and the entry gets added to the DB but my action function cannot destructure the data from the response because it's undefined. What is my stupid mistake?

You aren't returning a value from the function. Try
export const createPost = (newPost) => {
return axios.post(url, newPost);
}

Related

How to read POST data in sveltekit

Hi I am beginner in sveltekit. I try to get post data in sveltekit here is my POST Request.
I am using axios to send post data.
const request = await axios
.post("/api/user", {
username,
email,
password,
repassword
})
.then((e) => {
console.log(e)
})
.catch((e) => {
console.error(e);
});
and this is my POST Endpoint:
// src/routes/user/+server.ts
export const POST = async({request}) => {
console.log(request)
return new Response(JSON.stringify({something: 1}))
}
this api working fine with GET methods.
Looks like the routes just don't match.
src/routes/user/+server.ts equates to just /user.

Error handling API calls with axios Interceptors. Am I doing this right?

Hello I'am completly new with React/Redux so there is a possibility that I violated some principles with the below code , so bare with me.
I'm building a React App which will consume my Express API. Everything is working perfectly but when I was building the Action Creators I couldnt think of a good way to handle any errors coming from the API without wrapping every single axios request with try/catch blocks.
Both in PHP world where I come from and Express you can create a global Error handler.
For any async requests in my Express APP I wrap them with the below function so I can catch them the same way as the synchronous.
module.exports = (fn) => {
return (req, res, next) => {
fn(req, res, next).catch((err) => next(err));
};
};
From what I've learned through googling is that, there is an ErrorBoundary HOC for handling errors inside Components and for axios calls I should use axios interceptors. So I created this:
AxiosFactory Class
import axios from "axios";
import { setError } from "../actions/utilActions";
import store from "../store";
class AxiosFactory {
constructor(baseURL) {
this.instance = axios.create({
baseURL,
});
this.instance.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
// Getting the errors from Express API
const {
response: {
data: { errors },
},
} = error;
store.dispatch(setError(errors));
return Promise.reject(error);
}
);
}
getInstance() {
return this.instance;
}
}
export default AxiosFactory;
User API Caller
import AxiosFactory from './AxiosFactory';
const axios = new AxiosFactory('/api/v1/users/').getInstance();
export default axios;
User ActionCreator
import { SUCCESS_LOGIN } from "./types/userTypes";
import userApi from "../apis/user";
// Tries to login the user
export const signInUser = () => {
return async (dispatch) => {
// Test
const {data:{data:{user} = await userApi.post("login", {
email: "test#test.com",
password: "test12345!",
});
dispatch({
type: SUCCESS_LOGIN,
payload: user,
});
}
Error ActionCreator
import { HAS_ERROR } from "./types/utilTypes";
export const setError = (errors) => {
return async (dispatch) => {
dispatch({
type: HAS_ERROR,
payload: errors,
});
};
};
The interceptor dispatches succesfuly the setError and the error state is getting updated like a charm, which means I dont need to manual dispatch on each call. Although I still need to catch the Promise rejection from Interceptor.
My 2 questions are:
Is there a way to lets say "stop the dispatch from executing" inside my User ActionCreator without try/catching the Promise ?
Does this whole thing I setup makes sense ? Or there is a better way to do it?

React Redux is not working as expected with Next.js & NodeJS

I'm working on an app using Next.js with redux by following this example and here is some part of store.js
// REDUCERS
const authReducer = (state = null, action) => {
switch (action.type){
case actionTypes.FETCH_USER:
return action.payload || false;
default:
return state;
}
}
export const rootReducer = combineReducers({
user: authReducer,
form: reduxForm,
});
// ACTIONS
export const fetchUser = () => {
return (dispatch) => {
axios.get('/api/current_user')
.then(res => dispatch({
type: actionTypes.FETCH_USER,
payload: res.data
}));
};
};
export const submitLogin = (values) => async dispacth => {
const res = await axios.post('/api/login', values);
// Router.push('/');
// console.log(res)
dispacth({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });
};
and the client side such as header
function mapStateToProps (state) {
const { user } = state
return { user }
}
export default connect(mapStateToProps)(Header)
and when I console.log('############=>', this.props.user); the props & I'm not loggesd in then it's showing null but showing some extra data such as below screenshot
but when I logged in & console.log('############=>', this.props.user); it's showing proper data without extra data such as below image
what I'm doing wrong? please help me. Thanks
The problem is probably not on your React / Redux code but on your Next.js routes.
You’re trying to call an API with axios.get('/api/current_user') but Next.js is giving you an HTML response, that you indeed store in authReducer extracting it as action.payload.
You probably want to see this section about Custom Server and Routing.
dispacth({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });
Should be:
dispatch({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });
#MunimMunna is spot on. Your server is either redirecting you to an HTML login page, or returning an HTML error page for failed creds. In either case, Axios is seeing a 200 status code, so it thinks the response is valid. Your action creator blindly fires off the action with the HTML payload attached.
Consider making these changes:
Client:
Add a catch block to your axios promise that logs failed response.
Pass an Accept header of application/json to tell the server you don't want HTML responses. If you are lucky, this might be enough to get NextJS to behave the way you want.
Server: If needed, change the server to detect whether the request is an XHR request, or if application/json is the only response type the client wants. Don't redirect if those conditions are true. Return return a 401 status code instead. You can optionally return a JSON body with some extra error information.

Receving "500 Internal Server Error" on Post Request to Firebase-Cloud-Function Endpoint

I'm trying to make a POST request using axios to my firebase cloud-function on form submit in react app. But I get '500' error everytime I make a request with an html-page response This app works best with javascriot enabled.
Latest Update:
It looks like there is no issue with cloud function
code. Rather more of a react-component issue. I used Postman to send
the POST request with header prop Content-Type set to application/json
and sending body in raw format {"email": "example_email"} and got
expected response from the cloud function. But when sent the request from
react component above, I get an html file response saying the app
works best with javascript enabled
I've tried setting Content-Type to both Application/json and multipart/form-data as I suspected it to be an issue but still got no luck.
Following is my code for cloud function and react submit form:
Cloud Function
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true })
const runThisFunc1 = require(./libs/runThisFunc1);
const runThisFunc2 = require(./libs/runThisFunc2);
exports.wizardFunc = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let email = request.body.email;
try {
return runThisFunc1(email)
.then(data => {
console.log("Word Done by 1!");
return runThisFunc2(data);
})
.then(res => {
console.log("Word Done by 2!");
return response.status(200).send("Success");
})
.catch(err => {
console.error("Error: ", err.code);
return response.status(500).end();
});
}catch(err) {
return response.status(400).end();
}
});
});
React-Form-Component Snippet
import axios from 'axios'
...
handleSubmit = e => {
e.preventDefault()
const { email } = this.state
axios({
method: 'post',
url: `${process.env.REACT_APP_CLOUD_FUNCTION_ENDPOINT}`,
data: { email: email },
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
})
.then(res => {
//do something with reponse here
})
.catch(error => {
console.error(error)
})
}
...
Is there something wrong I am doing in the code or the request config is wrong?

Get request yields response with data in it, but when accessing .data specifically it yields undefined

Apologies if the terminology is not great, still new to fullstack.
Hello! I am trying to get all the users in my DB. The get() response is OK as the client is receiving the response (see image below)
The problem is that when I try to fetch the .data I get undefined.
Here's my Vue Component
import UserService from '#/services/UsersService.js'
export default {
data () {
return {
users: null
}
},
async mounted () {
// GET request for all users.
this.users = UserService.index().data
console.log('The response is OK', await UserService.index())
console.log('when trying to fetch the .data I am getting ', await this.users)
}
}
The index() function
import Api from '#/services/Api'
export default {
index () {
return Api().get('users')
}
}
Everything works fine, except that I get undefined data...
I think you forgot to fetch the data asynchronously?
async mounted () {
// GET request for all users.
- this.users = UserService.index().data
+ const res = await UserService.index()
+ this.users = res.data
console.log('The response is OK', await UserService.index())
console.log('when trying to fetch the .data I am getting ', await this.users)
}
You correctly use await syntax in the first console.log, which might explain why the data return correctly.

Categories

Resources