This is React native expo mobile app. I'm using NodeJs Server to get data from Firestore. Postman api fetch data properly.
Cannot fetch data from react native mobile app.
Postman Output
"customer": [
{
"phone":12345,
"username": "customer1",
},
]
Redux action.js
import { SET_CUSTOMERS } from "../types";
import { create } from "axios";
import { auth } from "../../firebase";
const baseURL = "https://...../api/";
const API = create({
baseURL: baseURL,
timeout: 60000,
"Content-Type": "application/json",
});
export const getCustomers = () => {
return async (dispatch) => {
try {
const token = await auth.currentUser.getIdToken();
console.log("token ", token); //Working Well
const response = API({
url: "customers",
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(response); //NOT Working
dispatch({ type: SET_CUSTOMERS, payload: response.data });
} catch (error) {
console.log(error);
throw error;
}
};
};
Redux reducer.js
import { SET_CUSTOMERS } from "../types";
const initialState = {
customers: [],
};
export default (state = initialState, action) => {
switch (action.type) {
case SET_CUSTOMERS:
return {
...state,
customers: action.payload,
};
default:
return state;
}
};
import React, { useState, useEffect, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getCustomers } from "../store/actions/data";
const UserProfileView = (props) => {
const [error, setError] = useState();
const customers = useSelector((state) => state.data.customers);
const dispatch = useDispatch();
const loadCustomers = useCallback(async () => {
setError(null);
try {
await dispatch(getCustomers());
} catch (err) {
setError(err.message);
}
}, [dispatch, setError]);
useEffect(() => {
loadCustomers;
}, [loadCustomers]);
return (
<View>
<Text>Customer Details</Text>
</View>
);
};
Expected Output payload: response.data pass response.data array
export const getCustomers = () => {
return async (dispatch) => {
try {
const token = await auth.currentUser.getIdToken();
console.log("token ", token); //Working Well
const response = API({
url: "customers",
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(response); //NOT Working
dispatch({ type: SET_CUSTOMERS, payload: response.data });
} catch (error) {
console.log(error);
throw error;
}
};
};
Related
Can someone tell me what mistake I am making or tell me how to set the header in axios patch request. when I am running the API through postman, everything is working fine but when I connect it with the front end, an error comes up saying that the JWT is not provided on the backend
here is the frond end code :
import React, { useEffect } from 'react';
import { useParams } from 'react-router';
import axios from 'axios';
const Loader = () => {
const parmas = useParams();
const { id } = parmas;
console.log(id);
useEffect(() => {
const fetchBags = async () => {
try {
const res = await axios.patch('http://localhost:4001/public/verify', {
headers: {
'Content-Type': 'application/json',
Token: id,
},
});
console.log(res);
console.log('CBM', { res });
} catch (error) {
console.log(error);
}
};
fetchBags();
}, []);
return <div>this is loader</div>;
};
export default Loader;
below is my backend code:
export const verifyUser = async (data) => {
const token1 = data.header("Token");
try {
const verified = jwt.verify(token1, getTokenSecret());
console.log(verified)
await userModel.verifyUser(verified);
return {
message: "success",
};
} catch (error) {
console.log(`Auth Service > verifyUser > ${error.toString()}`);
throw error;
}
};
this error is comming:
Error
From docs
axios.patch(url[, data[, config]])
As you can see you pass config in 3rd argument not 2nd.
const res = await axios.patch(
'http://localhost:4001/public/verify',
{}, // data (2nd argument)
{
headers: {
'Content-Type': 'application/json',
Token: id,
},
} // config (3rd argument)
)
I make web application using react js, node, express
when I login the error message appear says "No token attached"
now I need to put a jwt token into header how can I do that
this is my code:
import { webToken } from "../crypto/web_token.js";
import { responses } from "../classes/responses.js";
export const verifyRequest = (req, res, nex) => {
try {
if (!req.headers.authorization) {
throw Error("no token attached");
}
const token = req.headers.authorization.split(" ")[1];
const payload = webToken.verify(token);
req.user = payload;
nex();
} catch (error) {
res.json(new responses.Error(error.message));
}
};
another code: web_token.js
import jsonwebtoken from "jsonwebtoken";
import { errors } from "../classes/errors.js";
const secret = "#########";
export const webToken = Object.freeze({
generate: (data, expiry = "1hr") => {
try {
return jsonwebtoken.sign(data, secret, { expiresIn: expiry });
} catch (error) {
throw new errors.Logic("Internal error from the bcrypt hashing", "jwt");
}
},
verify: (token) => {
try {
const data = jsonwebtoken.verify(token, secret);
return data;
} catch (error) {
throw new errors.Authentication(
error.message.replace("jwt", "Token"),
"jwt"
);
}
},
});
here is the template, take a look
var axios = require('axios');
var data = JSON.stringify({
"value1": "val1"
});
var config = {
method: 'post',
url: 'http://localhost:3000/GetText',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
I'm creating a to-do list that uses authentication and the todo has to connect to the MongoDB server. The bad request is because of syntax, probably the to-do list sending back from client-side to server-side. How do I fix this error?
This is the page the error is on: TodoPage.js
import React, { useState, useEffect } from 'react';
//components
import ToDoList from '../Components/ToDoList';
import ToDoForm from '../Components/ToDoForm';
function ToDoPage() {
const [toDoList, setToDoList] = useState([]);
const url = 'http://localhost:8080/todo';
useEffect(function effectFunction() {
fetch(url, {
method: 'POST',
mode: 'no-cors',
})
.then((response) => response.json())
.then(({ data: toDoList }) => {
setToDoList(toDoList);
});
}, []);
const handleToggle = (id) => {
let mapped = toDoList.map((task) => {
return task.id === Number(id)
? { ...task, complete: !task.complete }
: { ...task };
});
setToDoList(mapped);
};
const handleFilter = () => {
let filtered = toDoList.filter((task) => {
return !task.complete;
});
setToDoList(filtered);
};
const addTask = (userInput) => {
let copy = [...toDoList];
copy = [
...copy,
{ id: toDoList.length + 1, task: userInput, complete: false },
];
setToDoList(copy);
};
return (
<div className='App'>
<ToDoList
toDoList={toDoList}
handleToggle={handleToggle}
handleFilter={handleFilter}
/>
<ToDoForm addTask={addTask} />
</div>
);
}
export default ToDoPage;
The console says it is this block of code that is giving trouble.
useEffect(function effectFunction() {
fetch(url, {
method: 'POST',
mode: 'no-cors',
})
.then((response) => response.json())
.then(({ data: toDoList }) => {
setToDoList(toDoList);
});
}, []);
the code below is the first request for get list data
mounted() {
this.getList()
},
methods: {
handleClick(row) {
console.log(row.id)
console.log(row.url)
this.$router.push({ name: 'Main', query: { id: row.id } })
},
getList() {
axios
.get('/api/v1/requests/all', {
params: {
userId: this.$store.state.userInfo.id,
},
})
.then(response => {
let moment = require('moment')
for (var item of response.data.data) {
item.createdAt = moment(item.createdAt).format(
'YYYY-MM-DD HH:mm:ss',
)
}
this.items = response.data.data
})
.catch(error => {
console.log(error)
})
}
my interceptor
axios.interceptors.response.use(
function (response) {
return response
},
async function (error) {
const originalRequest = error.config
if (error.response.status === 401 && !originalRequest._retry) {
error.response.config._retry = true
sessionStorage.removeItem('access-token')
let headers = {
grant_type: 'refresh_token',
Authorization: sessionStorage.getItem('refresh-token'),
}
axios
.post('/api/v1/users/refresh_token', {}, { headers: headers })
.then(response => {
let token = response.data.data
sessionStorage.setItem('access-token', token)
originalRequest.headers['Authorization'] = token
originalRequest.headers['grant_type'] = 'grant_type'
return axios.request(originalRequest)
})
.catch(error => {
console.log(error)
alert('blablabla.')
})
}
return Promise.reject(error)
},
)
the flow is i understand
1.token expired
2.move to list page
3.mounted hook is request data
4.getList -> axios get('~~request/all')
5.interceptor->axios post('~~~refresh_token')
6.re request with new token(request/all)
7.re request is 200, but not update list page
i'd really appreciate your help :)
Seems like you need to return the second request (await for result and return). Right now the result of second request seems to be ignored
axios.interceptors.response.use(
function (response) {
return response;
},
async function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
error.response.config._retry = true;
sessionStorage.removeItem("access-token");
let headers = {
grant_type: "refresh_token",
Authorization: sessionStorage.getItem("refresh-token"),
};
const [secondError, res] = await axios // await here
.post("/api/v1/users/refresh_token", {}, { headers: headers })
.then(async (response) => {
let token = response.data.data;
sessionStorage.setItem("access-token", token);
originalRequest.headers["Authorization"] = token;
originalRequest.headers["grant_type"] = "grant_type";
return [null, await axios.request(originalRequest)];
})
.catch((err) => {
console.log(err);
alert("blablabla.");
return [err, null];
});
// Handle here
if(secondError) {
return Promise.reject(secondError);
}
return Promise.resolve(res)
}
return Promise.reject(error);
}
);
The above solution worked for me perfectly. here's the modified code that I used for my requirement.
export default function axiosInterceptor() {
//Add a response interceptor
axios.interceptors.response.use(
(res) => {
// Add configurations here
return res;
},
async function (error) {
const originalRequest = error.config;
let secondError, res
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
[secondError, res] = await axios({
method: "POST",
url: `${baseURL}/account/token/refreshtoken`,
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
.then(async (response) => {
//handle success
return [null, await axios.request(originalRequest)];
}).catch(function (error) {
console.error(error)
});
}
if (secondError) {
return Promise.reject(secondError);
}
return Promise.resolve(res)
}
);
}
Postman gets the data correctly but axios get the wrong data, it receives the "Not found" but there is a record in DB.
react hook:
import axios from "axios";
import {useEffect, useState} from "react";
export default function useRoom(roomName) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [room, setRoom] = useState({})
useEffect(() => {
setLoading(true)
axios({
method: "POST",
body: {
"roomName": "test1"
},
withCredentials: true,
url: "http://localhost:4444/room",
}).then(res => {
setRoom(res.data)
console.log(res)
setLoading(false)
}).catch(e => {
setError(e.toString())
setLoading(true)
})
}, [roomName])
return {
error,
room,
loading
}
}
NODE JS:
app.post('/room', (req, res) => {
Room.findOne({roomName: req.body.roomName}, async (err, doc) => {
if (err) throw err;
if (!doc) res.send("No Room Found");
else {
res.send(doc);
}
})
})
Postman receives the data but the axios doesn't
I have the data in my db
What I get in the browser console:
How I use my hook:
If someone knows how to solve this issue please let me know
I'm not sure but maybe you should use 'data' instead of 'body' :
axios({
method: "POST",
data: { // <--- HERE
"roomName": "test1"
},
withCredentials: true,
url: "http://localhost:4444/room",
})