I would like to explain my problem of the day.
this is the part of the code that works
here I recovered 2 data "title" and "quantity" here it works very well
postbackend = () => {
const newItems = this.props.items.map((item) => {
const { title, quantity, } = item;
return {
title,
quantity,
};
});
const config = {
method: "POST",
headers: {
"Content-Type": "application/json",
};
body: JSON.stringify({ ...this.state, items: newItems,
};
const url = entrypoint + "/alluserpls";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
this.props.history.replace("/OrderSummaryPaymentFalseScreen"); // Your Error Page
} else {
alert(`film ajouté avec l'ID ${res}!`);
this.props.history.push("/OderSummaryScreen"); // Your Success Page
}
}).catch(e => {
console.error(e);
this.props.history.replace("/OrderSummaryPaymentFalseScreen"); // Your Error Page
}).finally(() => this.setState({
redirect: true
}));
so i tried this ,and I would like to separate "title" and "quantity".
example like this
const newItems = this.props.items.map((item) => {
const { title } = item;
return {
title,
};
});
const newQuantity = this.props.items.map((item) => {
const { quantity } = item;
return {
quantity,
};
});
const config = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ ...this.state, items: newItems, quantityforproduct: newQuantity,
};
but it doesn't work
Do you have an idea of how to fix this? Neff
Related
As you can in the react (clint-side) code , i am trying increase/decrese of Quantity in database and UI.
in this code i am sucessfully show quantity in console . but i don't show it my UI and database . Now what should i do ?
Server side (react)
const { register, handleSubmit } = useForm();
const onSubmit = (data, event) => {
const url = https://nameless-dusk 43671.herokuapp.com/products/${productsId}
fetch(url, {
method: "PUT",
headers: {
'content-type': "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(result => {
console.log(result)
event.target.reset()
}
)
}
update item on clint side
app.put('/products/:id', async (req, res) => {
const id = req.params.id;
const updateUser = req.body;
const filter = { _id: ObjectId(id) }
const options = { upsert: true };
const updateDoc = {
$set: {
name: updateUser.name,
email: updateUser.email,
}
}
const result = await
ProductCollection.updateOne(filter, updateDoc,
options)
res.send(result)
})
I have an react application connected to a database. Currently the app takes the database when it mounts and uses that to populate the state. The apps allows someone to post to the database. So far that works.
The issue is that I want the new posted content to be seen by the user. As it is the content only populates after I reload the page. I tried to repeat the coding in the componentDidMount() in a function that runs after the POST request, but for someone reason that is not working.
class App extends Component {
state = {
notes: [],
folders: [],
//noteID: 0,
//folderID: 0
};
componentDidMount() {
Promise.all([
fetch(`${config.API_ENDPOINT}/notes`),
fetch(`${config.API_ENDPOINT}/folders`)
])
.then(([notesRes, foldersRes]) => {
if (!notesRes.ok)
return notesRes.json().then(e => Promise.reject(e))
if (!foldersRes.ok)
return foldersRes.json().then(e => Promise.reject(e))
return Promise.all([
notesRes.json(),
foldersRes.json(),
])
})
.then(([notes, folders]) => {
this.setState({ notes, folders })
})
.catch(error => {
console.error({ error })
})
}
pageReload = () =>{
//console.log('pageReload ran');
Promise.all([
fetch(`${config.API_ENDPOINT}/notes`),
fetch(`${config.API_ENDPOINT}/folders`)
])
.then(([notesRes, foldersRes]) => {
if (!notesRes.ok)
return notesRes.json().then(e => Promise.reject(e))
if (!foldersRes.ok)
return foldersRes.json().then(e => Promise.reject(e))
return Promise.all([
notesRes.json(),
foldersRes.json(),
])
})
.then(([notes, folders]) => {
this.setState({ notes, folders })
})
.catch(error => {
console.error({ error })
})
}
folderSubmit = (f) => {
//console.log("folderSubmit ran " + f);
const newFolder = { "name" : f };
const postfolder = {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(newFolder)
};
fetch(`${config.API_ENDPOINT}/folders`, postfolder).then(this.pageReload())
}
It looks like you are not setting your state after post. see below where you need to set your state.
folderSubmit = (f) => {
//console.log("folderSubmit ran " + f);
const newFolder = { "name" : f };
const postfolder = {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(newFolder)
};
fetch(`${config.API_ENDPOINT}/folders`, postfolder)
.then(response => response.json())
.then(data => this.setState(data));
}
I have a PUT route in the backend for liking posts, it adds the users id to the likes array in the post. This works fine when tested on Postman (by providing the post in the body) and the likes array is updated. However, when the icon is clicked in the frontend, I want the likes array to update but I'm not sure how to update the state for the post. result is showing the response in the frontend with a 200 status code but that's as far as I'm getting.
How can I update the likes array in the frontend?
Post.js
const Post = (props) => {
const [post, setPost] = useState({});
const [error, setError] = useState(false);
const id = props.match.params.id;
const loadSinglePost = (id) => {
read(id).then((data) => {
if (error) {
console.log(data.error);
setError(data.error);
} else {
setPost(data);
console.log(data);
}
});
};
useEffect(() => {
loadSinglePost(id);
}, [props]);
const like = (id) => {
const {user: { _id }, token} = isAuthenticated();
fetch(`${API}/like/${_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
id: id,
}),
})
.then(result => { console.log(result)})
.catch((err) => {
console.log(err);
});
};
return (
<div>
<Navbar />
<div>
<h3>{post && post.title}</h3>
<p>
{post && post.author ? post.author.name : ""}
</p>
<p>{post && post.body}</p>
<h5>{post && post.likes && post.likes.length} likes</h5>
<img
onClick={() => {
like(id);
}}
alt="..."
/>
</div>
</div>
);
};
export default Post;
controllers/post.js
exports.like = (req, res) => {
Post.findByIdAndUpdate(req.body._id, {
$push: {likes: req.profile._id}
}, {new: true}).exec((err, result) => {
if (err) {
return res.status(422).json({error: err})
} else {
return res.json(result)
}
})
}
exports.readById = (req, res) => {
const id = req.params.id
Post.findById(id)
.then(post => res.json(post))
.catch(err => res.status(400).json('Error: ' + err));
}
You can update likes in post in then callback like this:
const like = (id) => {
const {user: { _id }, token} = isAuthenticated();
fetch(`${API}/like/${_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
id: id,
}),
})
.then(result => {
// here update post likes
let updatedPost = {...post}; //to make copy of post
updatedPost.likes = [...updatedPost.likes, id]; //add new id to updatedPost' likes array
setPost(updatedPost); //update post
console.log(result)
})
.catch((err) => {
console.log(err);
});
};
Also from front-end you're sending id key in body:
body: JSON.stringify({
id: id, // here
})
And at back end you're expecting _id
Post.findByIdAndUpdate(req.body._id, { // here
$push: {likes: req.profile._id}
}
I am trying to create a playlist on localhost and then have the list I created to be saved to Spotify. Can someone help why Save to Spotify button might not be working? Everything else seems fine, I have doubts about the fetching part I used but can't figure out what the issue might be.
Screenshot of the page:
And there is the Spotify.js code:
import { SearchBar } from '../components/SearchBar/SearchBar';
const clientId = 'I've put my client id';
const redirectUri = 'http://localhost:3000/callback/';
let accessToken;
const Spotify = {
getAccessToken() {
if (accessToken) {
return accessToken;
}
//check for access token match
const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
if (accessTokenMatch && expiresInMatch) {
accessToken = accessTokenMatch[1];
let expiresIn = Number(expiresInMatch[1]);
//This clears the parameters, allowing to grab new access token then it expires
window.setTimeout(() => (accessToken = ''), expiresIn * 1000);
window.history.pushState('Access Token', null, '/');
return accessToken;
} else {
const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;
window.location = accessUrl;
}
},
search(term) {
const accessToken = Spotify.getAccessToken();
return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
headers: { Authorization: `Bearer ${accessToken}` },
})
.then((response) => {
return response.json();
})
.then((jsonResponse) => {
if (!jsonResponse.tracks) {
return [];
}
return jsonResponse.tracks.items.map((track) => ({
id: track.id,
name: track.name,
artists: track.artists[0].name,
album: track.album.name,
uri: track.uri,
}));
});
},
savePlaylist(name, trackUris) {
if (!name || !trackUris.length) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = { Authorization: `Bearer ${accessToken}` };
let userId;
return fetch(`https://api.spotify.com/v1/me`, { headers: headers })
.then((response) => response.json())
.then((jsonResponse) => (userId = jsonResponse.id))
.then((userId) => {
return fetch(`/v1/users/${userId}/playlists`, {
headers: headers,
method: 'POST',
body: JSON.stringify({ name: name }),
})
.then((response) => response.json())
.then((jsonResponse) => {
const playlistId = jsonResponse.id;
return fetch(`/v1/users/${userId}/playlists/${playlistId}/tracks`, {
headers: headers,
method: 'POST',
body: JSON.stringify({ uris: trackUris }),
});
});
});
},
};
export default Spotify;
Here is the screenshot of Element > Console:
I had an fetch error, updated as below and working now.
let accessToken;
const Spotify = {
getAccessToken() {
if (accessToken) {
return accessToken;
}
//check for access token match
const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
if (accessTokenMatch && expiresInMatch) {
accessToken = accessTokenMatch[1];
let expiresIn = Number(expiresInMatch[1]);
//This clears the parameters, allowing to grab new access token then it expires
window.setTimeout(() => (accessToken = ''), expiresIn * 1000);
window.history.pushState('Access Token', null, '/');
return accessToken;
} else {
const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;
window.location = accessUrl;
}
},
search(term) {
const accessToken = Spotify.getAccessToken();
return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
headers: { Authorization: `Bearer ${accessToken}` },
})
.then((response) => {
return response.json();
})
.then((jsonResponse) => {
if (!jsonResponse.tracks) {
return [];
}
return jsonResponse.tracks.items.map((track) => ({
id: track.id,
name: track.name,
artists: track.artists[0].name,
album: track.album.name,
uri: track.uri,
}));
});
},
savePlaylist(name, trackUris) {
if (!name || !trackUris.length) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = { Authorization: `Bearer ${accessToken}` };
let userID;
return fetch('https://api.spotify.com/v1/me', { headers: headers })
.then((response) => response.json())
.then((jsonResponse) => {
userID = jsonResponse.id;
return fetch(`https://api.spotify.com/v1/users/${userID}/playlists`, {
method: 'POST',
headers: headers,
body: JSON.stringify({ name: name }),
})
.then((response) => response.json())
.then((jsonResponse) => {
const playlistID = jsonResponse.id;
return fetch(
`https://api.spotify.com/v1/users/${userID}/playlists/${playlistID}/tracks`,
{
method: 'POST',
headers: headers,
body: JSON.stringify({ uris: trackUris }),
}
);
});
});
}, // end of savePlaylist method
}; // end of Spotify object
export default Spotify;
I have a reactjs app that should be returning data from a WepAPI. The dispatch I call on a function seems to be giving me this error: TypeError: Cannot read property 'then' of undefined
I have used other functions through dispatch and it worked fine but this one still sticks out.
The intended result is for the data to get back to the initial dispatch. At the moment the data comes through but is stuck when returning to the initial call.
import React from 'react';
import { connect } from 'react-redux';
import { jobActions } from '../../actions/job.actions';
import Popup from 'reactjs-popup'
import JwPagination from 'jw-react-pagination';
class LoadTable extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
pagination: [],
Search: "Search",
sort: {
column: null,
direction: 'desc',
},
}
this.clearSearch = this.clearSearch.bind(this);
this.doSearch = this.doSearch.bind(this);
this.doSort = this.doSort.bind(this);
this.runLog = this.runLog.bind(this);
this.openRunLog = this.openRunLog.bind(this);
this.onChangePage = this.onChangePage.bind(this);
}
componentDidMount() {
this.props.getJobs()
.then((res) => {
this.setState({
data: res.results.response || []
})
});
}
clearSearch() {
this.props.getJobs()
.then((res) => {
this.setState({
data: res.results.response || [], Search: "Search",
sort: {
column: null,
direction: 'desc',
}
})
});
}
doSearch(e) {
const { name, value } = e.target;
this.setState({ [name]: value });
this.props.doSearch(value)<----Initial Call
.then((res) => {
this.setState({
data: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
render() {
return (
use data
)}
const mapDispatchToProps = dispatch => ({
getJobs: () => dispatch(jobActions.getJobs()),
doSearch(value) {
dispatch(jobActions.doSearch(value));<----dispatch
},
});
export default connect(mapStateToProps, mapDispatchToProps)(LoadTable);
==========================================
Action being called:
function doSearch(value) {
return (dispatch) => {
dispatch({ type: jobConstants.JOB_REQUEST });
return jobService.doSearch(value)
.then(
results => {
dispatch({ type: jobConstants.JOB_SUCCESS, user });
//Ran console logs and seen the results here
return { results };
},
error => {
dispatch({ type: jobConstants.JOB_FAILURE, error });
}
);
}
}
=========================
Services
function doSearch(SearchValue) {
const requestOptions = {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8'
}),
body: JSON.stringify({SearchValue})
};
const requestPath = 'http://localhost:53986/api/jobs/postsearch';
return fetch(requestPath, requestOptions)
.then(handleResponseToJson)
.then(response => {
if (response) {
return { response };
}
}).catch(function (error) {
return Promise.reject(error);
});
}
You need an async function for your service, which returns a promise. Like this
async function doSearch(val) {
const requestOptions = {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8'
}),
body: JSON.stringify({SearchValue})
};
const requestPath = 'http://localhost:53986/api/jobs/postsearch';
const data = fetch(requestPath, requestOptions);
const jsonData = await data.json();
return jsonData;
}
Then you can call like so:
doSearch(val).then() // and so on...
This is the pattern your looking for in this case.