401 error searching Spotify - javascript

I keep getting the following error no matter what i do:
https://api.spotify.com/v1/search?type=track&q=eminem 401 (Unauthorized)
I think i am getting the access token (see the code below) but for some reason it is not registering. The code for the methods are below and underneath that is the main page for the app where the methods are being used. Any help you can give is greatly appreciated!
Spotify.js
export const Spotify = {
**getAccessToken()** {
if (accessToken) {
return new Promise(
resolve => resolve(accessToken)
);
} else {
const accessTokenCheck = window.location.href.match(/access_token=([^&]*)/);
const expiresInCheck = window.location.href.match(/expires_in=([^&]*)/);
if (accessTokenCheck && expiresInCheck) {
accessToken = accessTokenCheck;
const expiresIn = expiresInCheck;
window.setTimeout(() => accessToken = '', expiresIn * 1000);
window.history.pushState('Access Token', null, '/');
} else {
window.location = 'https://accounts.spotify.com/authorize?client_id=' + clientId + '&response_type=token&scope=playlist-modify-public&redirect_uri=' + redirectURI;
}
return new Promise(
resolve => resolve(accessToken)
);
}
},
**search(term)** {
return Spotify.getAccessToken().then( () => {
return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`
, {
headers: {
Authorization: `Bearer ${accessToken}`
}
}).then(
response => response.json()
).then(
jsonResponse => {
if (jsonResponse.tracks) {
return jsonResponse.tracks.items.map(track => {
return {
id: track.id,
name: track.name,
artist: track.artists[0].name,
album: track.album.name,
uri: track.uri
};
});
}
}
)
})
},
**savePlaylist(playlistName,trackURIs)**{
if(playlistName && trackURIs){
const currentUserAccessToken = accessToken;
const headers = {Authorization: window.location.href.match(/access_token=([^&]*)/)};
const userID = null;
fetch('https://api.spotify.com/v1/me',{headers: headers}).then(response => {
if (response.ok){
return response.json();
}
throw new Error('Request failed!');
}, networkError => console.log(networkError.message)
).then(jsonResponse => {
const userID = jsonResponse.id;
});
fetch('https://api.spotify.com/v1/users/{user_id}/playlists', {
headers: headers,
method: 'POST',
body: JSON.stringify({id: '200'})
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Request failed!');
}, networkError => console.log(networkError.message)
).then(jsonResponse => {
const playlistID = jsonResponse.id;
});
}
else{
return playlistName && trackURIs;
}
}
};
export default Spotify;
App.js
search(term){
Spotify.search(term).then(tracks=>{
this.setState({
tracks:tracks
})
});
}
// {tracks: {items: {[rest of data]}}}
render() {
return (
<div>
<div className="App">
<SearchBar onSearch={this.search}/>
<div className="App-playlist">
<SearchResults onAdd={this.addTrack} searchResults={this.state.search} />
<Playlist onRemove={this.removeTrack} playlistName={this.state.playlistName} playlistTracks ={this.state.playlistTracks} onNameChange={this.updatePlaylistName} onSave={this.savePlaylist} />
</div>
</div>
</div>
);
}
}

Related

Create shareable ObjectURL from blob

So, I am creating a walkie talkie website\app but the problem is that when I record the audio and convert the bolb to objectUrl it works only in the sender's device. I did some research and found out that createObjectURL only works in local env. How do I send it.
Here is my index.js:
// index.js
import Head from 'next/head';
import { useEffect, useState } from 'react';
import style from '../../../styles/Talk.module.css';
import apiBaseUrl from '../../../components/apiBaseUrl';
const talk = ({ id }) => {
const [paused, setPaused] = useState(false);
const [copied, setCopied] = useState(false);
const [webScokect, setWebScokect] = useState();
const [participants, setParticipants] = useState(0);
const [userId, setUserId] = useState();
const [stream, setStream] = useState();
const [mediaRecorder, setMediaRecorder] = useState();
useEffect(() => {
const ws = new WebSocket(`ws://localhost:8080`);
setWebScokect(ws);
ws.onmessage = async (e) => {
const data = JSON.parse(e.data);
if (data.status === 'failure') {
return alert('technical error');
}
if (data.status === 'success') {
if (data.type === 'handShake') {
try {
const res = await fetch(
`${apiBaseUrl}/register?roomId=${id}&userId=${data.data.randomId}`
);
const mydata = await res.json();
if (mydata.status === 'failure') {
return alert('technical error');
}
setUserId(data.data.randomId);
setParticipants(mydata.data.participants);
} catch (error) {
return alert('technical error');
}
} else {
console.log(data.data.blob);
const audio = new Audio(data.data.blob);
audio.play();
}
}
};
}, []);
const sendBlobToServer = (audioUrl) => {
webScokect.send(
JSON.stringify({
roomId: id,
userId,
blob: audioUrl,
})
);
};
const handleClick = async () => {
if (paused) {
mediaRecorder.stop();
stream.getTracks().forEach(function (track) {
track.stop();
});
} else {
const userMedia = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const userRocrder = new MediaRecorder(userMedia);
userRocrder.start();
const audioChunks = [];
userRocrder.addEventListener('dataavailable', (event) => {
audioChunks.push(event.data);
});
userRocrder.addEventListener('stop', () => {
const audioBlob = new Blob(audioChunks);
const audioUrl = URL.createObjectURL(audioBlob);
sendBlobToServer(audioUrl);
});
setStream(userMedia);
setMediaRecorder(userRocrder);
}
setPaused(!paused);
};
const handleCopy = () => {
navigator.clipboard.writeText(`http://localhost:3000/talk/${id}`);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1500);
};
return (
<div className={style.container}>
<Head>
<title>In room: {id}</title>
</Head>
<img
src="/walkietalkie-talk.png"
alt="walkie-talk"
className={style.walkieTalkieImage}
onClick={handleClick}
/>
<img
src="/record.png"
alt="record"
className={`${style.record} ${paused && style.show}`}
/>
<p className={style.getInviteLink} onClick={handleCopy}>
{copied ? 'Copied' : 'Copy invite link'}
</p>
<p className={style.memberCount}>{participants} members in room</p>
</div>
);
};
export async function getServerSideProps(context) {
const { id } = context.params;
return {
props: { id },
};
}
export default talk;
And app.js ws code:
// app.js
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws, req) => {
const randomId = v4().substring(0, 15);
ws.id = randomId;
ws.send(
JSON.stringify({
status: 'success',
type: 'handShake',
data: {
randomId,
},
})
);
ws.on('message', (data) => {
try {
const jsonData = JSON.parse(data);
if (!jsonData.roomId || !jsonData.blob || !jsonData.userId) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (
typeof jsonData.roomId !== 'string' ||
typeof jsonData.userId !== 'string' ||
typeof jsonData.blob !== 'string'
) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
Room.findOne({ roomId: jsonData.roomId }, (err, result) => {
if (err) {
console.log(err);
} else {
if (!result) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
if (!result.users.includes(jsonData.userId)) {
return ws.send(
JSON.stringify({
status: 'failure',
})
);
}
wss.clients.forEach(function each(client) {
if (
client.id !== jsonData.userId &&
result.users.includes(client.id)
) {
client.send(
JSON.stringify({
status: 'success',
type: 'message',
data: {
blob: jsonData.blob,
},
})
);
}
});
}
});
} catch {
ws.send(
JSON.stringify({
status: 'failure',
})
);
}
});
});

Stop multiple request sent on refresh token using axios-auth-refresh

I am using axios-auth-refresh axios interceptor 3rd party library to handle my refresh token, the issue is that i have multiple request on my dashboard around 10 request and every time when the token expires, it will execute the my refresh token function multiple times and based on how many requests that are made. I previously refer to this stackoverflow question but it didn't somehow work on me and some requests are not being made then I opt at using axios-auth-refresh library to handle my refresh token function, because I thought that the option pauseInstanceWhileRefreshing: true will help me prevent it but it didn't somehow work.
What I want to achieve is to execute a single refresh token request to the server while other requests are on queue (I am using cookie to store my token), once it successfully replace the token then it will retry or resend those request back to the server. Below is my code:
import axios from 'axios';
import axiosRetry from 'axios-retry';
import config from 'config';
import {isNull, isUndefined} from 'underscore';
import Cookies from 'universal-cookie';
import createAuthRefreshInterceptor from 'axios-auth-refresh';
const api_client = () => {
const client = axios.create({baseURL: config.server});
const cookies = new Cookies();
client.interceptors.request.use(request => {
const cookies = new Cookies();
const cookieToken = cookies.get('token');
const cookieUser = cookies.get('user');
if(!isNull(cookieToken) && !isNull(cookieUser)) {
if(!isUndefined(cookieToken.token)) {
request.headers['Authorization'] = `Bearer ${cookieToken.token}`;
}
request.withCredentials = true;
request.headers['Content-Type'] = 'application/json'
request.headers['X-Fname'] = cookieUser.username;
}
return request;
}, error => {
console.log(error);
});
const handleRefreshAuth = failedRequest => {
return getRefreshAuthToken().then(response => {
if(response.data) {
cookies.remove("token", { domain: window.location.hostname, path: "/grt" });
cookies.remove("token", { domain: window.location.hostname, path: "/" });
cookies.set("token", { token: response.data.token, refreshToken: response.data.refreshToken, }, { domain: window.location.hostname, path: "/grt", expires: new Date(Date.now() + 259200) });
failedRequest.response.config.headers['Authorization'] = `Bearer ${response.data.token}`;
return Promise.resolve();
}
})
}
const options = {
pauseInstanceWhileRefreshing: true
}
createAuthRefreshInterceptor(client, handleRefreshAuth, options);
const getRefreshAuthToken = () => {
return new Promise((resolve, reject) => {
const cookieToken = cookies.get('token');
const cookieUser = cookies.get('user');
if((!isNull(cookieToken) && !isNull(cookieUser)) || (!isUndefined(cookieToken) && !isUndefined(cookieUser))) {
client.post(`/user/refresh?refreshToken=${cookieToken.refreshToken}`).then(response => {
if(response) {
resolve(response)
}
})
}
})
}
return client;
}
export const retrieve = async (url, data = undefined) => {
return new Promise(async (resolve, reject) => {
await api_client().get(url, data).then(response => {
if(response) {
resolve(response.data);
}
})
})
}
export const send = async (url, data = undefined) => {
return new Promise(async (resolve, reject) => {
await api_client().post(url, data, { skipAuthRefresh: true }).then(response => {
if(response) {
resolve(response.data);
}
})
})
}
export default {retrieve, send};
Network
Old code
I added this one as well, it might be that I missed something else on this one, using raw axios interceptor method, same issue as the new one.
import axios from 'axios';
import axiosRetry from 'axios-retry';
import config from 'config';
import {isNull, isUndefined} from 'underscore';
import Cookies from 'universal-cookie';
const api_client = () => {
const client = axios.create({baseURL: config.server});
let isRefreshing = false;
let failedQueue = [];
const retryCodes = [
401
]
axiosRetry(client, {
retries: 3,
retryDelay: (retryCount) => {
return retryCount * 1000;
},
retryCondition: (error) => {
return retryCodes.includes(error.response.status);
}
});
client.interceptors.request.use(request => {
const cookies = new Cookies();
const cookieToken = cookies.get('token');
const cookieUser = cookies.get('user');
if(!isNull(cookieToken) && !isNull(cookieUser)) {
if(!isUndefined(cookieToken.token)) {
request.headers['Authorization'] = `Bearer ${cookieToken.token}`;
}
request.withCredentials = true;
request.headers['Content-Type'] = 'application/json'
request.headers['X-Fname'] = cookieUser.username;
}
return request;
}, error => {
console.log(error);
});
const processQueue = (error, token = null) => {
const cookies = new Cookies();
console.log('processQueue', token)
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
const cookieToken = cookies.get('token');
prom.resolve(cookieToken.token);
}
})
failedQueue = [];
}
const getRefreshAuthToken = async () => {
return new Promise(async (resolve, reject) => {
const cookies = new Cookies();
const cookieToken = cookies.get('token');
const cookieUser = cookies.get('user');
if((!isNull(cookieToken) && !isNull(cookieUser)) || (!isUndefined(cookieToken) && !isUndefined(cookieUser))) {
await client.post(`/user/refresh?refreshToken=${cookieToken.refreshToken}`).then(response => {
if(response) {
resolve(response)
}
})
}
})
}
client.interceptors.response.use(response => {
return response;
}, error => {
const originalRequest = error.config;
const cookies = new Cookies();
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise(function(resolve, reject) {
failedQueue.push({ resolve, reject });
}).then(response => {
if(response) {
console.log('from test response', response)
cookies.remove("token", { domain: window.location.hostname, path: "/grt" });
cookies.remove("token", { domain: window.location.hostname, path: "/" });
cookies.set("token", { token: response.data.token, refreshToken: response.data.refreshToken, }, { domain: window.location.hostname, path: "/grt", expires: new Date(Date.now() + 259200) });
originalRequest.headers['Authorization'] = `Bearer ${cookies.get('token').token}`;
return client(originalRequest);
}
}).catch(error => {
return Promise.reject(error);
});
}
originalRequest._retry = true;
isRefreshing = true;
return new Promise((resolve, reject) => {
getRefreshAuthToken()
.then(response => {
if(!isUndefined(response)) {
cookies.remove("token", { domain: window.location.hostname, path: "/grt" });
cookies.remove("token", { domain: window.location.hostname, path: "/" });
cookies.set("token", { token: response.data.token, refreshToken: response.data.refreshToken, }, { domain: window.location.hostname, path: "/grt", expires: new Date(Date.now() + 259200) });
}
processQueue(null, cookies.get('token').token);
resolve(client(originalRequest));
}).catch(error => {
// add to queue for failed requests
processQueue(error, null);
reject(error);
}).then(() => {
isRefreshing = false
});
});
}
return Promise.reject(error);
})
return client;
}
export const retrieve = async (url, data = undefined) => {
return new Promise(async (resolve, reject) => {
await api_client().get(url, data).then(response => {
if(response) {
resolve(response.data);
}
})
})
}
export const send = async (url, data = undefined) => {
return new Promise(async (resolve, reject) => {
await api_client().post(url, data, { skipAuthRefresh: true }).then(response => {
if(response) {
resolve(response.data);
}
})
})
}
export default {retrieve, send};
Does anyone knows how to fix this? If so, please let me know, thanks!

Issue while using the Following component in React,.The User get's added to the NavBar as if it was me

Ok, this is gonna be hard to explain, but I have a bug that I don't know how to fix. I have a Follow component, where i make a call to the backend to add the user as a follower/following. The function itself works, but when I change the state of the dynamicUser, that User get's added to my navBar and I can access the Profile. I'm sharing my whole code so maybe any of you guys can point me on what is wrong. Thanks in advance!
Follow component
const Follow = ({ userId, user, setUser }) => {
const [error, setError] = useState(null);
const [follow, setFollow] = useState([]);
const classes = useStyles();
const handleFollow = (e) => {
e.preventDefault();
const accessToken = localStorage.getItem(CONST.ACCESS_TOKEN);
axios
.put(
`${CONST.SERVER_URL}${PATHS.USER}/${userId}${PATHS.FOLLOW_USER}`,
{ user },
{ headers: { authorization: accessToken } }
)
.then((response) => {
console.log("BASH", response);
setError(null);
if (!response.status) {
return setError(response);
}
setUser(response?.data);
})
.catch((error) => {
console.log("ERROR", error);
});
};
const handleUnFollow = (e) => {
e.preventDefault();
const accessToken = localStorage.getItem(CONST.ACCESS_TOKEN);
axios
.put(
`${CONST.SERVER_URL}${PATHS.USER}/${userId}${PATHS.UNFOLLOW_USER}`,
{ user },
{ headers: { authorization: accessToken } }
)
.then((response) => {
console.log("Are you?", response);
setError(null);
if (!response.status) {
return setError(response);
}
setUser(response.data);
})
.catch((error) => {
console.log(error);
});
};
return (
<div>
{user.following[0] === userId ? (
<form onSubmit={handleUnFollow}>
<Button
className={classes.unFollow}
variant="contained"
color="secondary"
type="submit"
startIcon={<PersonAddDisabledIcon />}
>
UnFollow
</Button>
</form>
) : (
<form onSubmit={handleFollow}>
<Button
className={classes.follow}
variant="contained"
color="primary"
type="submit"
startIcon={<PersonAddIcon />}
>
Follow
</Button>
</form>
)}
</div>
);
};
Parent component
const SingleUser = (props) => {
const { user, setUser } = props;
const [dynamicUser, setDynamicUser] = useState({});
const [isLoading, setIsLoading] = useState(true);
const classes = useStyles();
useEffect(() => {
setIsLoading(true);
axios
.get(`${CONST.SERVER_URL}/users/${props.match.params.userId}`, {
headers: { authorization: localStorage.getItem(CONST.ACCESS_TOKEN) },
})
.then((response) => {
setDynamicUser(response.data);
})
.catch((err) => {
console.log(err.response);
})
.finally(() => {
setIsLoading(false);
});
}, [props.match.params.userId]);
if (isLoading) {
return <LoadingComponent />;
}
console.log("DYNAMIC", dynamicUser);
return (
<div>
<Grid className={classes.button} raise elevation={3}>
<Follow userId={dynamicUser._id} user={user} setUser={setUser} />
</Grid>
)
}
this will likely either solve the issue, or make it clearer from error messages where the issue is
// ...
const Follow = ({ userId, user, setUser }) => {
const [error, setError] = useState(null);
const [follow, setFollow] = useState([]);
const classes = useStyles();
const handleFollow = () => {
return new Promise(async (resolve, reject) => {
try {
const accessToken = localStorage.getItem(CONST.ACCESS_TOKEN);
const url = `${CONST.SERVER_URL}${PATHS.USER}/${userId}${PATHS.FOLLOW_USER}`
const response = await axios.put(url, { user }, { headers: { authorization: accessToken } })
console.log("BASH", response);
setError(null);
if (!response.status) throw response
setUser(response.data);
resolve()
} catch (err) {
setError(err.response.data)
console.log("ERROR", err);
reject(err)
}
})
};
// try catch blocks are easier to troubleshoot with promises
const handleUnFollow = () => {
return new Promise(async (resolve, reject) => {
try {
const accessToken = localStorage.getItem(CONST.ACCESS_TOKEN);
const url = `${CONST.SERVER_URL}${PATHS.USER}/${userId}${PATHS.UNFOLLOW_USER}`
const response = await axios.put(url, { user }, { headers: { authorization: accessToken } })
console.log("Are you?", response);
if (!response.status) throw response
setError(null);
setUser(response.data);
resolve();
} catch (err) {
console.error(err);
setError(err.response.data);
reject(err);
}
})
};
// i made some purely syntactical changes - i've always felt this was
// more readable in my own code to wite them out this way
const hasUserId = user.following[0] === userId
return (
<div>
<form
onSubmit={async e => {
e.preventDefault();
if (hasUserId) {
await handleUnFollow()
} else {
await handleFollow()
}
}}
>
<Button
className={hasUserId ? classes.unFollow : classes.follow}
variant="contained"
color={hasUserId ? 'secondary' : 'primary'}
type="submit"
startIcon={hasUserId ? <PersonAddDisabledIcon /> : <PersonAddIcon />}
>
{hasUserId ? 'UnFollow' : 'Follow' }
</Button>
</form>
</div>
);
};
const SingleUser = (props) => {
const { user, setUser } = props;
const [dynamicUser, setDynamicUser] = useState({});
const [isLoading, setIsLoading] = useState(true);
const classes = useStyles();
useEffect(() => {
return new Promise(async (resolve, reject) => {
try {
setIsLoading(true);
const url = `${CONST.SERVER_URL}/users/${props.match.params.userId}`
const headers = { authorization: localStorage.getItem(CONST.ACCESS_TOKEN) }
const response = await axios.get(url, { headers })
setDynamicUser(response.data);
setIsLoading(false);
resolve()
} catch (err) {
console.log(err.response.data);
reject(err)
}
})
// im not sure what this part does, since useEffect is never called
// however using promises is much easier to troubleshoot bugged out code
}, [props.match.params.userId]);
if (isLoading) {
return <LoadingComponent />;
}
console.log("DYNAMIC", dynamicUser);
return (
<div>
<Grid className={classes.button} raise elevation={3}>
<Follow userId={dynamicUser._id} user={user} setUser={setUser} />
</Grid>
</div>
)
}
so I ended up fixing this, and the problem was actually on the backend, cause I was sending the wrong user, but now everything works. I'll still will put my code here cause there seem to be a problem with the unFollow.
//follow user
router.put("/:userId/follow", isLoggedIn, async (req, res) => {
try {
const user = await User.findById(req.params.userId);
const currentUser = await User.findById(req.body.user._id);
const follow = await User.findByIdAndUpdate(
currentUser,
{ $addToSet: { following: user } },
{ new: true }
);
await User.findByIdAndUpdate(user, {
$addToSet: { followers: currentUser },
});
return res.json(follow);
} catch (err) {
return res.status(500).json({ error: err });
}
});
//unFollow the user
router.put("/:userId/unFollow", isLoggedIn, async (req, res) => {
try {
const user = await User.findById(req.params.userId);
const currentUser = await User.findById(req.body.user._id);
const follow = await User.findByIdAndUpdate(
currentUser,
{ $pull: { following: user } },
{ new: true }
);
await User.findByIdAndUpdate(user, {
$pull: { followers: currentUser },
});
return res.json(follow);
} catch (err) {
return res.status(500).json({ error: err });
}
});

javascript/react/redux async await refactoring

I would like to refactor the fetchRelationships function to use async await. I am not sure what the best way is to do it as this code contains nested .then at response.json().then((json) =>....
Could sby pls post the refactored version?
export const fetchRelationshipsError = (error) => {
return {
type: FETCH_RELATIONSHIPS_FAILURE,
payload: { error }
};
};
export const fetchRelationshipsRequest = () => {
return { type: FETCH_RELATIONSHIPS_REQUEST };
};
export const fetchRelationshipsSuccess = (relationships) => {
return {
type: FETCH_RELATIONSHIPS_SUCCESS,
payload: relationships
};
};
export const fetchRelationships = (url) => {
return (dispatch) => {
dispatch(fetchRelationshipsRequest());
fetch(url, config)
.then((response) => {
const responseObj = {
response: response,
payload: response.json().then((json) => {
return { body: json }
})
};
if (!response.ok) {
const error = new Error(response.statusText);
responseObj.payload.then((response) => {
show_error_alert(response.body);
dispatch(fetchRelationshipsError(response.body));
});
throw error;
}
return responseObj.payload;
})
.then((response) => {
dispatch(fetchRelationshipsSuccess(response.body))
})
.catch((error) => { console.log('Request failed', error); });
};
};
Solution:
export const fetchRelationships = (url) => {
return async (dispatch) => {
dispatch(fetchRelationshipsRequest());
try {
const response = await fetch(url, config);
const jsonResponse = await response.json();
if (!response.ok) {
show_error_alert(jsonResponse);
dispatch(fetchRelationshipsError(jsonResponse));
const error = new Error(response.statusText);
throw error;
}
dispatch(fetchRelationshipsSuccess(jsonResponse));
} catch(error) {
console.log('Request failed', error);
}
};
};
Ill take a stab at this:
export const fetchRelationshipsError = (error) => {
return {
type: FETCH_RELATIONSHIPS_FAILURE,
payload: { error }
};
};
export const fetchRelationshipsRequest = () => {
return { type: FETCH_RELATIONSHIPS_REQUEST };
};
export const fetchRelationshipsSuccess = (relationships) => {
return {
type: FETCH_RELATIONSHIPS_SUCCESS,
payload: relationships
};
};
export const fetchRelationships = (url) => {
return async (dispatch) => {
dispatch(fetchRelationshipsRequest());
try{
const response = await fetch(url, config)
const jsonResponse = await response.json()
if(!response.ok){
show_error_alert(jsonResponse);
dispatch(fetchRelationshipsError(jsonResponse));
const error = new Error(response.statusText);
throw error;
}
dispatch(fetchRelationshipsSuccess(jsonResponse));
}catch(error){
console.log('Request failed', error);
}
};

How catch error from async action with redux?

I have fetch, it throws error:
fetchAuthorization(username, password) {
return fetch(`https://api.github.com/user`, {
method: 'GET',
headers: {
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": "Basic " + btoa(`${username}:${password}`)
},
})
.then(res => {
if(res.status !== 200) {
throw Error("Bad validation");
}
return res.json();
});
},
then this async action (redux):
export const onSignInAction = (username, password) => {
return dispatch => {
return api.fetchAuthorization(username, password)
.then( res => {
dispatch(signInAction(username, password, res));
})
.catch(err => console.log(err));
}
}
next:
handleSignIn = (username, password) => {
const { onSignInAction } = this.props;
onSignInAction(username, password);
}
And now I want catch Error from my fetch :
handleSignIn = () => {
const { onSignIn } = this.props;
const { errorMessage, open } = this.state;
const username = this.usernameField.getValue();
const password = this.passwordField.getValue();
try {
onSignIn(username, password);
}
catch (Error) {
this.setState({
errorMessage: 'Incorrect username or password'
});
}
}
How to catch it correctly? My code doesn't do this stuff. Thanks!
You can throw error from .catch(), substitute Promise.prototype.catch() for try..catch
var onSignInAction = () => {
return Promise.reject(new Error("Bad validation")).catch(e => {
console.log("catch 1", e.message);
throw e
});
}
onSignInAction()
.catch(err => {
console.log("catch 2:", {
errorMessage: 'Incorrect username or password'
}, err.message);
});

Categories