I know that method: DELETE, changes the isActive from true to false.
But how can I revert it back from false to true?
Here's my code to revert it, but I don't know what it lacks:
let params = new URLSearchParams(window.location.search)
let courseId = params.get('courseId')
let token = localStorage.getItem('token')
fetch(`http://localhost:3000/api/courses/${courseId}`, {
method: "PUT",
headers:{
'Authorization': `Bearer ${token}`
}
})
.then(res => res.json())
.then(data => {
if(data === true){
window.location.replace('./courses.html')
}else{
alert("Something went wrong.")
}
})
This is my routes:
router.put('/:courseId', auth.verify, (req, res) => { let courseId = req.params.courseId CourseController.unArchive({courseId}).then(resultFromUnArchive => res.send(resultFromUnArchive)) })
This is my controller:
module.exports.unArchive = (params) => {
let updateActive2 = {
isActive: true
}
return Course.findOneAndUpdate(params.courseId, updateActive2).then((course, err) => {
return (err) ? false : true
})
}
I've tried this and it doesn't work
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
isActive:true
})
Related
I am working on this issue from last 3 days. I dived through the stack overflow, but of no use. There are the questions about "Missing draft message", but I am still getting this message. I have tried all the ways they have said. but I am still here.
Here is my code
const str = "My Draft";
const msgBody = btoa(str);
var token = localStorage.getItem("accessToken");
fetch(
"https://gmail.googleapis.com/gmail/v1/users/me/drafts?key=[my api key] HTTP/1.1",
{
method:"post",
ContentType: 'application/json',
Accept: 'application/json',
headers: {
"Authorization": `Bearer ${token}`,
},
message: {
raw: msgBody
}
}
)
.then((data) => data.json())
.then((response) => console.log(response));
please add message in body https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options
const str = "My Draft";
const msgBody = btoa(str);
var token = localStorage.getItem("accessToken");
fetch(
"https://gmail.googleapis.com/gmail/v1/users/me/drafts?key=[my api key] HTTP/1.1",
{
method: 'POST',
ContentType: 'application/json',
Accept: 'application/json',
headers: {
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify({ // Here changed
message: {
raw: msgBody
}
}),
}
)
.then((data) => data.json())
.then((response) => console.log(response));
whenever I click the delete button its works fine but I don't get the output like " deleted successfully " its shows .then undefined..
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
if (data.error) {
console.log(data.error);
} else {
preload();
}
});
};
here is the delete category API call
export const deleteCategory = (userId, categoryId , token) => {
fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
},
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
It should be like this. deleteCategory needs to send only promise. Later where ever you are resolving you have to use then.
export const deleteCategory = (userId, categoryId , token) => {
return fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
}
})
};
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
preload();
}).catch(err => {
console.log(err);
})
};
I'm new in javascript. I've a async function getListBar. Inside getListBar i use return result of getAccount like a input of function fetch( you can see user.access_token) . Code run correct but i don't want call getAccount everytime i use getListBar. So how can i get result of getAccount and save it ?
I've tried many ways but promise very difficult to me , i don't know how to save result of it
async function getAccount() {
try {
let response = await fetch(apiAuthen,
{
method: 'POST',
headers: {
Accept: '*/*',
'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
'Content-Type': 'application/x-www-form-urlencoded',
'grant_type': 'password',
},
body: qs.stringify({
'grant_type': 'password',
'username': 'abc',
'password': 'abc',
'client_id': 'abc',
})
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
async function getListBar() {
try {
const user = await getAccount().then(user => { return user });
let response = await fetch(apiBar,
{
headers: {
'Authorization': 'Bearer ' + user.access_token
}
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
getAccount will return a Promise like this and i want save access_token in it
Promise {_40: 0, _65: 0, _55: null, _72: null}
_40: 0
_55: {access_token: "41b369f2-c0d4-4190-8f3c-171dfb124844", token_type: "bearer", refresh_token: "55867bba-d728-40fd-bdb9-e8dcd971cb99", expires_in: 7673, scope: "read write"}
_65: 1
_72: null
__proto__: Object
If it is not possible to simply store a value in the same scope that these functions are defined, I would create a Service to handle getting the user. Preferably in its own file
AccountService.js
class AccountService {
getAccount = async () => {
if (this.user) {
// if user has been stored in the past lets just return it right away
return this.user;
}
try {
const response = await fetch(apiAuthen, {
method: 'POST',
headers: {
Accept: '*/*',
Authorization: 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
'Content-Type': 'application/x-www-form-urlencoded',
grant_type: 'password'
},
body: qs.stringify({
grant_type: 'password',
username: 'abc',
password: 'abc',
client_id: 'abc'
})
});
const responseJson = await response.json();
this.user = responseJson.data; // store the user
return this.user;
} catch (error) {
console.log(`Error is : ${error}`);
}
// you should decide how to handle failures
// return undefined;
// throw Error('error getting user :(')
};
}
// create a single instance of the class
export default new AccountService();
and import it where needed
import AccountService from './AccountService.js'
async function getListBar() {
try {
// use AccountService instead
const user = await AccountService.getAccount().then(user => { return user });
let response = await fetch(apiBar,
{
headers: {
'Authorization': 'Bearer ' + user.access_token
}
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
You will still be calling getAccount each time in getListBar but it will only fetch when AccountService has no user stored.
Now i write in the different way
export default class App extends Component {
constructor() {
super();
this.state = {
accessToken: '',
users: [],
listBar: []
}
}
//Get Account
Check = () => {
getAccount().then((users) => {
this.setState({
users: users,
accessToken: users.access_token
});
}).catch((error) => {
this.setState({ albumsFromServer: [] });
});
}
//Get Account
getAccount() {
return fetch(apiAuthen,
{
method: 'POST',
headers: {
Accept: '*/*',
'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA===',
'Content-Type': 'application/x-www-form-urlencoded',
'grant_type': 'password',
},
body: qs.stringify({
'grant_type': 'password',
'username': 'abc',
'password': 'abc',
'client_id': 'abc',
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
users: responseJson.data,
accessToken: responseJson.data.access_token
});
return responseJson.data
})
.catch((error) => {
console.error(error);
});
}
//Get List Bar
getListBarFromServer() {
return fetch(apiBar, {
headers: {
'Authorization': 'Bearer ' + this.state.accessToken
}
}).then((response) => response.json())
.then((responseJson) => {
console.log(this.getListBarFromServer()) <---- Just run if console
this.setState({ listBar: responseJson.data });
return responseJson.data
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.getAccount();
this.getListBarFromServer();
}
render() {
return (
<View style={{ top: 100 }}>
<FlatList data={this.state.listBar} renderItem={({ item }) => {
return (
<View>
<Text>{item.bar_id}</Text>
</View>
)
}}>
</FlatList>
</View>
)
}
}
It's just run when i console.log(this.getListBarFromServer()) .Please explain to me why?
I am trying to fetch multiple requests in an order in React. There are 3 requests,
first one gathering encoded information from backend
get token from authentication server
use api with the token.
All of them must be in order. But I am having difficulties because of async fetch function. I can't reach fetch's response outside of .then() block.
To solve it, I used await / async. But it caused another problem. My 3 requests must be in a sequencial order. When I use async, order gets broken.
Here is the code.
class App extends Component {
constructor() {
super();
this.state = { code: '', encoded: '', access_token: '', refresh_token: '' };
}
getCarDetails() {
const carId = '2F3A228F6F66AEA580'
var query = 'https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/'.concat(carId).concat('/doors')
fetch(query, {
method: 'GET',
headers: {
'Authorization': 'Bearer '.concat(this.state.access_token),
'accept': 'application/json'
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err));
}
getToken() {
var post_data = {
grant_type: 'authorization_code',
code: this.state.code,
redirect_uri: 'http://localhost'
}
fetch('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token', {
method: 'POST',
headers: new Headers({
'Authorization': 'Basic '.concat(this.state.encoded),
'Content-Type': 'application/x-www-form-urlencoded'
}),
body: queryString.stringify(post_data)
})
.then(res => res.json())
.then(data => this.setState({ access_token: data.access_token, refresh_token: data.refresh_token }))
.catch(err => console.log(err));
}
getEncodedClientIdAndClientSecret() {
if (this.state.code != null) {
fetch('http://localhost:8000/encodeClientIdAndSecret', {
method: 'POST'
})
.then(res => res.json())
.then(data => this.setState({ encoded: data.encoded }))
.catch(err => console.log(err));
}
}
componentDidMount() {
const values = queryString.parse(this.props.location.search)
this.setState({ code: values.code })
console.log(this.state)
this.getEncodedClientIdAndClientSecret();
console.log(this.state) //this state is empty
//this.getToken();
//this.getCarDetails();
}
AWAIT / ASYNC
async getEncodedClientIdAndClientSecret() {
if (this.state.code != null) {
const response = await fetch('http://localhost:8000/encodeClientIdAndSecret', {
method: 'POST'
})
const data = await response.json();
console.log(data)
}
}
If I put await / async, I am having sequence problem between 3 requests.
in order to use async await on methods like
await getEncodedClientIdAndClientSecret();
await getToken();
you need to first return a promise from those functions like:
getToken() {
var post_data = {
grant_type: 'authorization_code',
code: this.state.code,
redirect_uri: 'http://localhost'
}
return fetch('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token', {
method: 'POST',
headers: new Headers({
'Authorization': 'Basic '.concat(this.state.encoded),
'Content-Type': 'application/x-www-form-urlencoded'
}),
body: queryString.stringify(post_data)
})
.then(res => res.json())
.then(data => this.setState({ access_token: data.access_token, refresh_token: data.refresh_token }))
.catch(err => console.log(err));
}
so it can wait for the promise to finish, othewise they will run in parallel and finish in random order.
I'm going to insert the whole module in case you need to see other aspects of the code. The call in question is the addTracks method. The project is to allow the person to search the spotify library, create a playlist of songs, then add the playlist to their account. Everything works fine, besides the tracks actually saving to the account, I get a 401 error on the API, but both Chrome and FireFox also label it as a GET call, instead of as a POST. The error is an authentication error, but I should be authorized correctly, the only odd thing for authorization is the scope, which is taken care of in the redirect in getAccessToken(). What am I missing here? In case you need it: Spotify add track documentation
let accessToken;
let expiresIn;
const clientId = '86f8f621d81a4ce18bd21da9fd2da2b1';
const redirectURI = 'http://localhost:3000/';
const Spotify = {
getAccessToken() {
if (accessToken) {
return accessToken;
} else if (window.location.href.match(/access_token=([^&]*)/) != null) {
accessToken = window.location.href.match(/access_token=([^&]*)/)[1];
expiresIn = window.location.href.match(/expires_in=([^&]*)/)[1];
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}`;
}
},
async search(term) {
if (accessToken === undefined) {
this.getAccessToken();
}
try {
let response = await fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`
}
});
if (response.ok) {
let jsonResponse = await response.json();
let tracks = jsonResponse.tracks.items.map(track => ({
id: track.id,
name: track.name,
artist: track.artists[0].name,
album: track.album.name,
uri: track.uri
}));
return tracks;
}
} catch (error) {
console.log(error);
}
},
async savePlaylist(name, trackURIs) {
if (accessToken === undefined) {
this.getAccessToken();
}
if (name === undefined || trackURIs === undefined) {
return;
} else {
let userId = await this.findUserId();
let playlistID;
fetch(`https://api.spotify.com/v1/users/${userId}/playlists`, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": 'application/json'
},
body: JSON.stringify({
name: name
})
}).then(response => {
return response.json()
}).then(playlist => {
playlistID = playlist.id;
this.addTracks(playlistID, trackURIs, userId);
});
}
},
addTracks(playlistID, trackURIs, userId) {
console.log(trackURIs);
fetch(`https://api.spotify.com/v1/users/${userId}/playlists/${playlistID}/tracks`), {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": 'application/json'
},
body: JSON.stringify({
uris: trackURIs
})
}
},
findUserId() {
if (accessToken === undefined) {
this.getAccessToken();
}
let userId;
return fetch(`https://api.spotify.com/v1/me`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
}).then(response => {
return response.json()
}).then(jsonResponse => {
userId = jsonResponse.id;
return userId;
});
}
};
export default Spotify;
I'm beginner but probably you should check bracket in fetch() method in addTracks()
addTracks(playlistID, trackURIs, userId) {
console.log(trackURIs);
fetch(`https://api.spotify.com/v1/users/${userId}/playlists/${playlistID}/tracks`->)<-, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": 'application/json'
},
body: JSON.stringify({
uris: trackURIs
})
}
},
correct
addTracks(playlistID, trackURIs, userId) {
console.log(trackURIs);
fetch(`https://api.spotify.com/v1/users/${userId}/playlists/${playlistID}/tracks`, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": 'application/json'
},
body: JSON.stringify({
uris: trackURIs
})
})
},