Uncaught (in promise) Error: Request failed with status code 404 - reactjs

I am getting above error while fetching some data from the API. Following is the code of the action creator where I am trying GET the data:
import { FETCH_USER } from './types';
import axios from 'axios';
export const fetchUser = () => async dispatch => {
console.log('fetchUser');
const res= await axios.get('/api/current_user');
dispatch({ type: FETCH_USER, payload: res });
};
Also when I am debugging in the code editor, console is giving me below error:
SyntaxError: Unexpected token import

Generally this error comes when the url/location provided inside GET method is not correct.
So check the url/location again and correct it.
So most probably there is some mistake here : '/api/current_user'

In my case it was a minor syntax error (a misplacement of my brackets).
My code looked like this:
axiosget("/api-url").then(
(response) => {
doSomething();
}), () => {
doError();
}
);
instead of this:
axiosget("/api-url").then(
(response) => {
doSomething();
}, () => {
doError();
});
);
If you get this error message it means that your error handling-code isn't there or that it could not be reached, therefore the promise was unhandled (since the catch-part of your wasn't properly setup).
If you get this message always doublecheck your syntax!

If your are using laravel for API and vue/Nuxtjs for frontend and axios for send data to API....
This type of errors can be faced for laravel validation error sending not in correct way using try{} catch(){} block or receiving errors by axios not in correct way to using try() catch(){} block.
Here, try catch block using for error handling.
If your API routes called the public function its name "register()", so your function inside your controller have to like following...(I am using laravel-8 for API)
public function register(Request $request) {
try {
$fields = $request->validate([
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
]);
$user = User::create([
'name' => $fields['name'],
'email' => $fields['email'],
'password' => bcrypt($fields['password'])
]);
$token = $user->createToken('myapptoken')->plainTextToken;
$response = [
'user' => $user,
'token' => $token,
];
return response()->json($response, 200);
} catch(ValidationException $e) {
return response()->json([
'status' => 'error',
'msg' => 'error',
'errors' => $e->errors()
], 422);
}
}
and Frontend Nuxt or vue methods name is "registerNewUser()" so, codes can be following for error handling...
async registerNewUser() {
try {
let data = {
name : this.name.trim(),
email : this.email.trim(),
password : this.password.trim(),
password_confirmation : this.password_confirmation.trim(),
};
let headers = {
headers: {
'Accept': 'application/json',
}
};
await this.$axios
.post("/api/register", data, headers)
.then((response) => {
console.log("response", response);
if(response) {
// console.log(response)
} else {
}
});
} catch(err) {
// here we are receiving validation errors
console.log("Err == ", err.response);
console.log(err.response.data.errors);
}
}
You are receiving response inside axios then block or receive error inside catch block using err.response
Here,
let data = {
name : this.name.trim(),
email : this.email.trim(),
password : this.password.trim(),
password_confirmation : this.password_confirmation.trim(),
};
Given codes is for data of Nuxtjs or vuejs. If not know that you can using like following data or any other data...
let data = {
name : 'Kallol',
email : 'kallolray94#gmail.com',
password : '123456',
password_confirmation : '123456',
};

Related

How To Only Show Error Messages When The Array is Not Empty in React Native

I am developing a react native application and I am using Laravel API to implement the Login functionality.
I have successfully created the functionality, now i am in the part of showing error messages to users if for instance the email field is empty and they click the login button.
This is being done by the Laravel Backend, and i am just accessing the error list that i am recieving from the API response and sending it as a value in the AuthContext that i created.
But when i add the code for the error messages it stays persistent even if the array is empty.
How do i only let the error be shown if it is present?
Here is my code:
AuthContext:
const [loginErrorList, setLoginErrorList] = useState([])
const [loginError, setLoginError] = useState(null)
const login = (email,password) => {
axios.get("/sanctum/csrf-cookie").then((response) => {
setIsLoading(true)
axios.post("/api/login", {
email,
password
}).then((res) => {
if (res.data.status === 200) {
console.log(res.data)
setIsLoading(false)
} else if (res.data.status === 401) {
setLoginError(res.data.message)
setIsLoading(false)
} else {
setLoginErrorList(res.data.validation_errors);
setIsLoading(false)
}
}).catch(e => {
console.log(e);
setIsLoading(false)
});;
});
}
return (
<AuthContext.Provider value={{
isLoading,
loginErrorList,
loginError,
login
}}>
{children}
</AuthContext.Provider>
)
LoginScreen.js:
const {isLoading, loginErrorList, loginError, login} = useContext(AuthContext);
return (
<TextInput
style={styles.input}
value={email}
placeholder="Enter email"
onChangeText={text => setEmail(text)}
/>
{loginErrorList == [] ? "" : <Text style={{color:"red"}}>{loginErrorList.email}</Text> }// this doesn't seem to work, and if the error list is empty it just leaves a white space below the input field.
)
Laravel AuthController:
public function login(Request $request){
$validator = Validator::make($request->all(),[
'email' => 'required|max:191',
'password' => 'required',
]);
if($validator->fails()){
return response()->json([
'validation_errors' => $validator->messages(),
]);
}else{
$user = User::where('email', $request->email)->first();
if(!$user || !Hash::check($request->password, $user->password)){
return response()->json([
'status' => 401,
'message' => "Incorret Email or Password",
]);
}else{
$token = $user->createToken($user->email . '_token',[''])->plainTextToken;
return response()->json([
'status' => 200,
'username' => $user->name,
'token' => $token,
'message' => 'Logged in Successfully',
]);
}
}
}
Your error is never being assigned to the context because the assignment occurs in your .then() block. .then() will only execute on successful API calls.
Replace the contents of your current .catch() with something like:
function (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
}
Then move the setLoginError() into your .catch() block function and pass it the error you are now catching.
loginErrorList == [] will never be true (try running [] == [] in the browser console). Instead of initializing loginErrorList as [] in AuthContext, initialize it as null and check if it is set before displaying the errors.
AuthContext.js:
const [loginErrorList, setLoginErrorList] = useState(null)
...
LoginScreen.js:
...
{loginErrorList && (
<Text style={{color:"red"}}>{loginErrorList.email}</Text>
)}

Backend validation fail throws "CORS policy" error

I am working on a user registration feature with frontend React and backend Laravel 8. When the input fields are valid it is working fine. But even if any of the input fields fail in the backend validation it throws an error saying "access has been blocked by CORS policy". Here is an image of the error. My question is why is everything working fine when the input fields are valid, but throwing an unrelatable error when it fails. And below is my code:
Frontend (React)
const register = async(values) => {
const {email, serial, password, confirm_password} = values;
const details = {email : email, serial : serial, password: password, password_confirmation : confirm_password};
try {
const result = await fetch('http://192.168.1.15:8000/api/v1/register', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(details),
})
const data = await result.json();
if (data.error) {
console.log(data.error)
}
else {
setUser(data.data)
cookies.set('Noortap', data.data, { path: '/' });
console.log(cookies.get('Noortap'))
}
}
catch (err) {
console.log(err)
}
}
Backend (Laravel)
public function register(Request $request)
{
$request->validate([
'name' => 'max:255',
'email' => 'required|unique:users,email|email|max:255',
'serial' => ['required','max:255', new IsValidSerialNumber],
'password' => 'required|confirmed',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'is_admin' => 0,
'password' => Hash::make($request->password)
]);
\App\Models\Tag::where('serial_number', $request->serial)->update([
'assigned' => 1,
'user_id' => $user->id
]);
// // response
// return $this->login($request);
return $request;
}
That is because your frontend and backend are on separate "domains". In this case, they are on the same domain but a different port. You will need to add http://192.168.1.15:3000 to the $except array in app/Http/Middleware/VerifyCsrfToken.php so that you dont face a CORS policy issue.
So your file should look something like this:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array<int, string>
*/
protected $except = [
'192.168.1.15:3000'
];
}

Trying to access JWT Authenticated Users content gives 401 in laravel

I have React frontend and Laravel Backend Application which authenticates user using JWT. The login process is working properly and I can get the authenticated user with the me function of JWT. But now when I try to access contents based on the authenticated user, I get 401 error. I'm adding my react axios function and also my laravel controller that has the function which is giving the error. Please point out what am I doing wrong on it. Any help is very much appreciated. Thank you.
React axios function:
export const fetchMyApplications = () => {
return async dispatch => {
const url = `/auth/my-applications`;
var formdata = new FormData();
const token = getCookie("userToken");
const response = await api
.get(
url,
{
headers: {
Authorization: `Bearer ${token}`
}
}
)
.then(res => {
return res;
})
.catch(error => {
return error.response;
});
dispatch({
type: "FETCH_MY_APLICATIONS",
payload: response
});
};
}
Laravel controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Models\Application;
class ApplyController extends Controller
{
public function __construct()
{
\Config::set('auth.providers.users.model', \App\Applicant::class);
$this->middleware('auth:api', ['except' =['personalDetails']]);
}
public function myApplications(){
try {
$user = auth()->userOrFail();
$applications = Application::where('applicant_id', $user->applicant_id)->with('course')->get();
return response()->json(['applications'=> $applications], 200);
}catch (\Tymon\JWTAuth\Exceptions\UserNotDefinedException $e) {
return response()->json(['status'=> false, 'errors'=> 'Unauthenticated User'], 401);
}
}
}
Auth Config:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
Postman Checking Logged In User:
Postman Trying to get applications of logged in user:
I figured out what was wrong. Actually it was not with my code, rather it was apache configuration on linode server. I added authorization header to the apache config file and it worked.

observable catchError after request failure (axios/redux)

INTRO :
I have an app in reactjs, using redux, redux-observable and axios-observable.
I face an issue with HTTP error handling.
Let's take the following Epic :
const loginRequest = (action$, state$) => action$.pipe(
ofType(UsersActions.loginRequest),
switchMap((action: {payload:{email: string, password: string}}) =>
HttpService.PostAsync<any>('token-auth', action.payload).pipe(
map(response => {
// blabla
}),
catchError((error: string) => {
// blabla
})
)
)
);
the HttpService looks like this
public static PostAsync<T>(targetApi: string, data: any, basePath?: string): AxiosObservable<T> {
return Axios.post(this.getBaseUrl(targetApi, basePath), data);
}
So this works correctly, if the post request fail, I get into the catchError, if it doesn't i go into the normal map.
PROBLEM :
I would like to intercept the response, in order to add a global app error handling, I setup the following function :
Axios.interceptors.response.use(response => {
console.log(`[response] --> ${response.status}`)
return response;
}, error => {
console.log(`[error] --> ${error}`)
return throwError(error);
})
I can now see the log, error, or response depending on the HTTP request result. BUT, I will ALWAYS go into the map, and never into the catchError of my Epic.
QUESTION :
How can I interpect the error, but still throw an error to the redux-observable epic ?
throwError only works within RX chain, try use native JS throw
Axios.interceptors.response.use(response => {
console.log(`[response] --> ${response.status}`)
return response;
}, error => {
console.log(`[error] --> ${error}`)
throw error
})

Console error "Bad Request" with Axios and Laravel

I'm using laravel 5.8 with react and axios. I built a login page and i get a console "bad request" error after login failed. I get the correct response from the server, but i keep getting the a console error of the post request.
Here is the request :
export const getProfile = () => {
return axios
.get('api/profile', {
headers: { Authorization: `Bearer ${localStorage.usertoken}` }
})
.then(response => {
return response.data
})
.catch(err => {
console.log(err)
})
}
And here is the login function from the UserController
public function login(Request $request)
{
$credentials = $request->json()->all();
try {
if (!$token = JWTAuth::attempt($credentials)) {
$loginsCount = 0; //init counter
if ($request->session()->has('userLoginsCount')) {
//get session value
$loginsCount = $request->session()->get('userLoginsCount');
//check login attempts count
if ($loginsCount == 5) {
$current_timestamp = now()->timestamp;
Log::info($current_timestamp.' User exceeded alowed
login attempts : '.$request->ip());
$request->session()->put('userLoginsCount', 0);
return;
} else {
//increment it
$loginsCount++;
// set the new value
$request->session()->put('userLoginsCount',
$loginsCount);
}
} else {
$request->session()->put('userLoginsCount', $loginsCount);
}
//Store session
Session::save();
return response()->json(['error' => 'invalid credentials'],
400);
}
} catch (JWTExecption $e) {
return response()->json(['error' => 'could not create token'], 500);
}
return response()->json(compact('token'));
}
Api Routes:
Route::post('register', 'UserController#register');
Route::post('login', 'UserController#login');
Route::get('profile', 'UserController#getAuthenticatedUser');
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Web Routes:
Auth::routes();
Route::get( '/{path?}', function(){
return view( 'layouts/app' );
} )->where('path', '.*');
Here pictures of the error
I believe these are the steps to fix everything.
1. Change error response to 401 (not authorized).
return response()->json(['error' => 'invalid credentials'], 401);
2. Retrieve the error message from the axios error response before use.
export const getProfile = () => {
return axios
.get('api/profile', {
headers: { Authorization: `Bearer ${localStorage.usertoken}` }
})
.then(response => {
return response.data
})
.catch(err => {
// retrieve the error message
let message = err.response.data.error;
console.log(message);
// now you can do something with 'message'
// ...
})
You were dumping the whole error to the console, not pulling out the actual message. I'm sorry I overlooked this.

Resources