Everytime I'm on my purchase page everything works and updates fine. When I hit submit for the first time in the page it updates my db correctly but alert window does not pop up. => Page rerenders and sets itself to initial view. If I stay on the page and submit a second purchase then I get a pop up box that says failure to fetch in post method and then the alert box saying that the purchase was successful pops up. Even though the failure occurred nothing is functionally wrong. All database documents are up to date. Somebody please help I have no clue what I'm doing wrong.
My front end react.js
import React, { useState, useEffect } from 'react';
import { NumberFormat as numberFormat } from '../numberFormat';
export default function Purchase() {
// user input collection structure
const [form, setForm] = useState({
amount: '',
title: '',
})
// user spending limit
const [limit, setLimit] = useState({
balance: 0,
limit: 0,
})
useEffect(() => {
async function getLimit() {
const response = await fetch(`http://localhost:4000/balance/`);
if (!response.ok) {
const message = `An error occured at effect: ${response.statusText}`;
window.alert(message);
return;
}
const data = await response.json();
const userBal = data["balance"];
const userLim = 50 - parseFloat(userBal);
setLimit({ balance: userBal, limit: userLim });
}
getLimit();
return;
}, []);
// Update State Properties
function updateForm(value) {
return setForm((prev) => {
return { ...prev, ...value };
});
}
function validateInput(input){
input = input * 1000;
if (input%10 === 0) return false;
else return true;
}
async function onSubmit() {
// check that amount is valid
if (form.title === ''){
window.alert(`Please Include a Title for the payment`);
return;
}
const bal = parseFloat(limit.balance);
const lim = parseFloat(limit.limit);
const amt = parseFloat(form.amount);
if (amt > lim || amt === 0 || amt === '' || validateInput(amt)){
window.alert(`Invalid Amount ${form.amount}.\nPlease enter value greater than 0.00 within ${lim}.`);
return;
}
const newPurchase = {
type: 'purchase',
amount: form.amount,
title: form.title,
balanceToSet: amt + bal
}
await fetch(`http://localhost:4000/purchase/add`, {
method: 'POST',
mode:'cors',
headers: {
'Access-Control-Allow-Origin': '*',
"Content-Type": 'application/json; charset=UTF-8',
},
body: JSON.stringify(newPurchase)
}
)
.then((response) => response.json()).then((data)=> {console.log(data);
})
.catch((err) => {
window.alert(`post fetch error ${err.message}`);
return;
});
window.alert(`Purchase ${form.title} of amount $${form.amount} posted.`);
return;
}
return (
// Will Display
<div className='home'>
{/* Title */}
<h1 className='hometitle'>
Make A Purchase
</h1>
<div>
<h1> Your Fizz Balance: {numberFormat(limit.balance)}</h1>
<h1> Your Fizz Allowance: {numberFormat(limit.limit)}</h1>
</div>
{/* Current Allowance */}
{/* Debt owed to fizz */}
{/* Make Purchase Form
If incorrect parameters then show text saying invalid amount below
On submission alert shows telling user a purchase of certain amount was made
render rest of the page */}
<form onSubmit={onSubmit}>
<div className="form-group">
<label htmlFor='title'>Title:</label>
<input
type='text'
id='name'
value={form.title}
onChange={(e) => updateForm({ title: e.target.value })}
/>
</div>
<div className="form-group">
<label htmlFor="amount">Amount:</label>
<input
type="text"
id="amount"
value={form.amount}
onChange={(e) => updateForm({ amount: e.target.value })}
/>
</div>
<div>
<input
type='submit'
value='Make Purchase'
/>
</div>
</form>
</div>
);
}
My backend node.js
const express = require("express");
const purchaseRoutes = express.Router();
const dbo = require("../db/connection");
const { floor } = require('mathjs');
// Add purchase to History Table and update balance in user info
purchaseRoutes.route("/purchase/add").post(
async function (req, response) {
let db_connect = dbo.getDb();
// Writing Purchase to History Table
let thisPurchase = {
type: req.body.type,
amount: parseFloat(req.body.amount),
title: req.body.title,
rfndStatus: false,
date: Date.now()
};
let queryParams = { name: "user" };
// post query contents
let updatedBalance = {
$set: {
balance: floor(req.body.balanceToSet * 1000) / 1000
}
};
const session = db_connect.startSession();
const transactionDetails = {
readPreference: 'primary',
readConcern: { level: 'local' },
writeConcern: { w: 'majority' }
}
try {
const transactionResults = await session.withTransaction(async () => {
const userColl = db_connect.db('fizzData').collection('userData');
const histColl = db_connect.db('fizzData').collection('transHist');
await userColl.updateOne(queryParams, updatedBalance,{session});
await histColl.insertOne(thisPurchase,{session});
}, transactionDetails);
response.json(transactionResults);
console.log(transactionResults);
} catch(e){
console.log(`transaction failed ${e}`)
}
finally {
await session.endSession();
}
});
I thought it could have been a cors issue so I installed the cors extension in chrome and added the mode tag to the header. The problem is not with the fetch in useEffect or at least the call because it correctly calls the right values from the database.
Seems like user agent is not aware that the form event is getting handled.
To resolve this, modify your onSubmit function as follows:
async function onSubmit(event) {
event?.preventDefault();
// ... rest of
// ... of the
// ... code
}
See if it works :)
EDIT: more info on above topic.
import "./styles.css";
export default function App() {
const onSubmit = (formEvent) => {
// if you comment this line
// you will see that console.log("Line got executed"); will print and the window will get reloaded and console.log is gone
formEvent.preventDefault();
// The above line with prevent reloading of the window
console.log("Line got executed");
};
const onButtonClick = (buttonEvent) => {
// if we comment this out the button will SUMBIT the form
buttonEvent.preventDefault();
// The above line with prevent submission of the form
// because this button is of type submit and it's default action is to submit the form
// so by adding above line we are disabling its default behavior
console.log("Button is clicked not for submission");
};
return (
<div className="App">
<form onSubmit={onSubmit}>
<input id="form-input" />
<button type="submit" onClick={onButtonClick}>
Submit or click
</button>
</form>
</div>
);
}
Codesandbox link to play around: https://codesandbox.io/s/react-preventdefault-udx49m?file=/src/App.js:0-1053
Related
I am trying to run my react app but process is not defined is coming up all the time. I am trying to connect with my smart contract using web3.js. My app.jsx file is,
import { useEffect, useState } from "react";
import Web3 from "web3";
import detectEthereumProvider from "#metamask/detect-provider";
import { loadContract } from "./utils/load-contract";
// m,dKK#;fl99
const App = () => {
const [web3Api, setWeb3Api] = useState({
provider: null,
web3: null,
contract: null,
});
const [account, setAccount] = useState(null);
useEffect(() => {
const loadProvider = async () => {
// console.log(window.web3);
// console.log(window.ethereum);
// let provider = null;
// if (window.ethereum) {
// provider = window.ethereum;
// } else if (window.web3) {
// provider = window.web3.currentProvider;
// } else if (!process.env.production) {
// provider = new Web3("http://127.0.0.1:7545");
// }
// try {
// await provider.enable();
// } catch (error) {
// console.log("error", error);
// }
const provider = await detectEthereumProvider();
const contract = await loadContract("Founder", provider);
console.log(contract);
// console.log(provider);
// console.log(prov)
if (provider) {
console.log("Ethereum successfully detected!");
provider.request({ method: "eth_requestAccounts" });
setWeb3Api({
web3: new Web3(provider),
provider,
contract,
});
} else {
console.error("Please install MetaMask!", error);
}
};
loadProvider();
}, []);
useEffect(() => {
const getAccount = async () => {
const acc = await web3Api.web3.eth.getAccounts();
setAccount(acc);
};
web3Api.web3 && getAccount();
}, [web3Api.web3]);
// console.log(web3Api.web3);
// console.log(account);
return (
<>
<div className="card text-center">
<div className="card-header">Funding</div>
<div className="card-body">
<h5 className="card-title">Balance: 20 ETH </h5>
<p className="card-text">
Account : {account ? account : "Not connected"}
</p>
{/*<button
type="button"
className="btn btn-success"
//connect to matamask
onClick={async () => {
const accounts = await window.ethereum.request({
method: "eth_requestAccounts",
});
console.log(accounts);
}}
> */}
{/* <button className="btn btn-success">Connect to metamask</button> */}
<button type="button" className="btn btn-success">
Transfer
</button>
<button type="button" className="btn btn-primary">
Withdraw
</button>
</div>
<div className="card-footer text-muted">Code Eater</div>
</div>
</>
);
};
export default App;
My load-contract file is,
import contract from "#truffle/contract";
export const loadContract = async (name, provider) => {
const res = await fetch(`/contracts/${name}.json`);
const Artifact = await res.json();
const _contract = contract(Artifact);
_contract.setProvider(provider);
const deployedContract = await _contract.deployed();
return deployedContract;
};
Now every time I run this app this error is kept coming,
Uncaught ReferenceError: process is not defined
at node_modules/util/util.js (util.js:109:1)
at __require2 (chunk-S5KM4IGW.js?v=0672b092:18:50)
at node_modules/#truffle/contract-schema/index.js (index.js:3:12)
at __require2 (chunk-S5KM4IGW.js?v=0672b092:18:50)
at node_modules/#truffle/contract/index.js (index.js:1:16)
at __require2 (chunk-S5KM4IGW.js?v=0672b092:18:50)
at index.js:15:18
Now why process is not defined is showing? What did i do wrong?
Now how to fix that. I am using node version 18.12.1 And i don't know how to solve this error. I can't find any good solution for this.
I created a comment session on my entertainment website
It’s working on backend.
It’s working on the frontend also but it’s not displaying the content the user typed on the database
This is my frontend (Comment form) logic:
export default function AddComment({ busy}) {
const [content, setContent] = useState("");
const { movieId } = useParams();
const { updateNotification } = useNotification();
const handleOnChange = ({ target }) => {
setContent(target.value);
};
const handleSubmit = async (e) => {
e.preventDefault();
const { error, message } = await addComment(movieId);
if (error) return updateNotification("error", error);
updateNotification("success", message);
const newComment = {
content,
};
setContent(newComment);
setContent("");
};
return (
<div className='p-5'>
<br />
<p className='dark:text-white text-primary'>replies</p>
<hr className='w-64' />
{/* Comment Lists */}
{/* Root Comment Form */}
{/* Form */}
<form className='flex ' onSubmit={handleSubmit} busy={busy}>
<textarea
value={content}
onChange={handleOnChange}
type='text'
autoComplete='text'
className='w-full rounded-md p-2 dark:text-white text-primary outline-none bg-transparent resize-none border-b focus:border-blue-500'
placeholder='Add New comment'
/>
<br className='dark:text-white text-primary ' />
<button
type='submit'
className=' w-5 h-14 dark:text-white text-primary bg-blue-600 hover:bg-blue-400 focus:border-blue-900 rounded-md'
>
{busy ? <ImSpinner3 className='animate-spin' /> : "Add"}
</button>
</form>
</div>
);
}
Then the addComment is coming from this API:
import { catchError, getToken } from "../utils/helper";
import client from "./client";
export const addComment = async (movieId, newComment) => {
const token = getToken();
try {
const { data } = await client.post(
`/comments/comment/${movieId}`,
newComment,
{
headers: {
authorization: "Bearer " + token,
},
}
);
return data;
} catch (error) {
return catchError(error);
}
};
The backend is working:
exports.createComment = expressAsyncHandler(async (req, res) => {
const { movieId } = req.params;
const { content } = req.body;
const userId = req.user._id;
console.log(req.body);
// verify user before comment
if (!req.user.isVerified)
return sendError(res, "Please verify your email first!");
if (!isValidObjectId(movieId)) return sendError(res, "Invalid Movie!");
// create and update new comment
const newComment = new Comment({
user: userId,
parentMovie: movieId,
content,
});
// save new comment
await newComment.save();
res.json({ message: "New comment added!!", newComment });
});
I posted with Postman on backend it gave me this on the database:
_id
:
62dcfccd93444cef55611632
user
:
62bf20d65073a7c65f549078
parentMovie
:
62c2c425465804ff32cdd06c
content
:
"hello"
createdAt
:
2022-07-24T08:03:25.666+00:00
updatedAt
:
2022-07-24T08:03:25.666+00:00
__v
:
0
on the console:
The port is listening on port 8000
connected to db
{ content: 'hello' }
POST /api/comments/comment/62c2c425465804ff32cdd06c 200 447.534 ms - 260
I posted on the frontend it gave me this on the database, no content:
_id
:
62dcfd6993444cef55611635
user
:
62bf57e8a8f3e737b2af23d9
parentMovie
:
62cc1d426785cfe42f8737a8
createdAt
:
2022-07-24T08:06:01.458+00:00
updatedAt
:
2022-07-24T08:06:01.458+00:00
__v
:
0
on the console it shows an empty object:
{}
POST /api/comments/comment/62cc1d426785cfe42f8737a8 200 364.009 ms - 242
This is how I solved the problem
Hope this solution will help many
const handleSubmit = async (e) => {
e.preventDefault();
const { error, message } = await addComment(movieId, content); // call the content and movieId from backend
if (error) return updateNotification("error", error);
updateNotification("success", message);
// push and display the content on database
const newComment = {
content,
};
setContent(newComment);
setContent("");
};
Then the API should be like this
export const addComment = async (movieId, newComment) => {
const token = getToken();
// console.log(newComment);
const body = {
content: newComment,
};
try {
const { data } = await client.post(`/comments/comment/${movieId}`, body, {
headers: {
authorization: "Bearer " + token,
},
});
return data;
} catch (error) {
return catchError(error);
}
};
My Goal for this one is to Add ObjectId inside the array
In my backend Im declare schema on this code:
tchStudents: [{
type: Schema.Types.ObjectId,
ref: "Student"
}]
THen Im do adding an ObjectId to insert to the array of ObjectID:
My BackEnd is very fine
router.put('/assignAddStudents/:tchID', async (req,res) => {
try {
const searchTch = await Teacher.findOne({ tchID: req.params.tchID })
if(!searchTch){
return res.status(404).send({
success: false,
error: 'Teacher ID not found'
});
} else {
let query = { tchID: req.params.tchID }
let assignedStudentObjID = {$push:{tchStudents: req.body.tchStudents }}
Teacher.updateOne(query, assignedStudentObjID ,() => {
try{
return res.status(200).send({
success: true,
msg: 'Student ID has been assigned'
});
} catch(err) {
console.log(err);
return res.status(404).send({
success: false,
error: 'Teacher ID not found'
})
}
})
}
} catch (err) {
console.log(err)
}
})
But my Front End Not working
err: BAD REQUEST(400) Unexpected token " in JSON at position 0
import React, {useState} from 'react'
import axios from 'axios'
import { URL } from '../../utils/utils'
import { Modal, Button } from 'react-materialize';
import ListTchStudents from '../lists/ListTchStudents';
const trigger =
<Button
style={{marginLeft:'2rem'}}
tooltip="Add More..."
tooltipOptions={{
position: 'top'
}}
className="btn-small red darken-4">
<i className="material-icons center ">add_box</i>
</Button>;
const MdlAddStudents =({teacher}) => {
const [data, setData] = useState('');
const { tchStudents} = data;
const {
tchID,
} = teacher; // IF WE RENDER THIS IT TURNS INTO OBJECT
const assignedStudent = () => {
// BUT WE SENT IT TO THE DATABASE CONVERT TO JSON.STRINGIFY to make ObjectId
const requestOpt = {
method: 'PUT',
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify(data)
}
axios.put(`${URL}teachers/assignAddStudents/${tchID}`, data,requestOpt)
.then(res => {
setData(res.data.data)
})
}
return (
<Modal header="Add Students" trigger={trigger}>
Please ADD and REMOVE Student ID No. for {tchID}
<div>
<ul
style={{marginBottom:'2rem'}}
className="collection">
{
Object.values(teacher.tchStudents).map(tchStudent => {
return(
<ListTchStudents
tchStudent={tchStudent}
/>
);
})
}
</ul>
<div className="row">
<div className="col s6 offset-s3"></div>
<div className="input-field">
<label
htmlFor=""
className="active black-text"
style={{fontSize:'1.3rem'}}>
Add Students here:
</label>
<input
type="text"
name="tchStudents"
value={(tchStudents)}
className="validate"
onChange={(e) => setData(e.target.value)}
/>
</div>
</div>
</div>
{/* BUT WE SENT IT TO THE DATABASE CONVERT TO JSON.STRINGIFY to send ObjectId to the database
*/}
<div className="row">
<div className="col s2 offset-s3" ></div>
<Button
onClick={assignedStudent}
tooltip="Add Students"
tooltipOptions={{
position: 'right'
}}
className="btn green darken-3">
<i className="material-icons ">add_circle</i>
</Button>
</div>
<p>There are {Object.values(teacher.tchStudents).length} student/s
assigned</p>
</Modal>
)
}
// MdlAddStudents.propTypes = {
// assignedStudents: PropTypes.func.isRequired,
// }
export default MdlAddStudents;
// export default connect(null, (assignedStudents))(MdlAddStudents);
Thank you for helping out
The problem stems from you attempting to wrap your tchStudents state property in an object named data.
My advice is to keep it very simple
// it's just a string
const [tchStudents, setTchStudents] = useState("")
const assignedStudent = () => {
// create your request payload
const data = { tchStudents }
// no config object required
axios.put(`${URL}teachers/assignAddStudents/${tchID}`, data)
.then(res => {
// not sure what you want to do here exactly but
// `res.data` should look like
// { success: true, msg: 'Student ID has been assigned' }
setTchStudents("") // clear the input ¯\_(ツ)_/¯
})
}
The only other change is to use the new setter name in your <input>...
<input
type="text"
name="tchStudents"
value={tchStudents}
className="validate"
onChange={(e) => setTchStudents(e.target.value)}
/>
i'm currently creating my first MERN App, and everything is going well, until something happened, and i'm going my try to explain because i need help !
What i'm doing is a facebook clone, where you can post something, you can delete your post and you can update your post, the logic is simple, i call dispatch to pass the data to the actions, the actions pass the data to the backend, and the backend return something to me and it saves in my store, because i'm using redux
The problem is that, when i have 2 post, and i want to delete a post, or maybe i want to edit it, the other post dissapears, it's like it loses its id and then loses the information, then i can't do anything but reaload the page, and it happens always
this is how it looks like, everything fine
Then, after trying to edit a post, the second one lost its information, and in the console, it says that Warning: Each child in a list should have a unique "key" prop, and i already gave each post the key={_id}, but the post lost it and i don't know how
Here's the code
Posts.js
import React, { useState } from "react";
import "./Posts.css";
import moment from "moment";
// Icons
import { BiDotsVertical, BiLike } from "react-icons/bi";
import { MdDeleteSweep } from "react-icons/md";
import { AiFillLike } from "react-icons/ai";
import { GrClose } from "react-icons/gr";
// Calling actions
import { deletePost, } from "../actions/posts.js";
// Gettin The Data From Redux
import { useSelector, useDispatch } from "react-redux";
const Posts = ({ setCurrentId }) => {
const [animation, setAnimation] = useState(false);
const [modal, setModal] = useState(false);
const [modalPost, setModalPost] = useState({});
// Getting The Posts
const posts = useSelector(state => state.posts);
const dispatch = useDispatch();
// Showing And Hiding Modal Window
const ModalWindow = post => {
setModalPost(post);
setModal(true);
};
// Liking the post
// const Like = id => {
// dispatch(giveLike(id));
// setAnimation(!animation);
// };
if (!posts.length) {
return <div>Loading</div>;
} else {
return (
<div className="Posts">
{/* // Modal window for better look to the post */}
{/* {modal && (
<div className="modalWindow">
<div className="container">
<div className="container-image">
<img src={modalPost.image} alt="" />
</div>
<div className="information">
<div className="container-information">
<div className="data-header">
<h2>
User <br />{" "}
<span style={{ fontWeight: "400" }}>
{moment(modalPost.createdAt).fromNow()}
</span>
</h2>
<span className="data-icon" onClick={() => setModal(false)}>
<GrClose />
</span>
</div>
<div className="message">
<h2>{modalPost.title}</h2>
<p>{modalPost.message}</p>
</div>
</div>
</div>
</div>
</div>
)} */}
{/* */}
{posts.map(post => {
const { _id, title, message, image, createdAt, likes } = post;
return (
<div className="Posts-container" key={_id}>
<div className="Fit">
<div className="Fit-stuff">
<h2 className="Fit-stuff_title">
User <br />{" "}
<span style={{ fontWeight: "400" }}>
{moment(createdAt).fromNow()}
</span>
</h2>
<a
className="Fit-stuff_edit"
href="#form"
onClick={() => setCurrentId(_id)}
>
<BiDotsVertical />
</a>
</div>
<div className="Fit-data">
<h2 className="Fit-data_title">{title}</h2>
<p className="Fit-data_message">{message}</p>
{image ? (
<div className="Fit-img">
<img
onClick={() => ModalWindow(post)}
src={image}
alt=""
/>
</div>
) : (
<div></div>
)}
</div>
<div className="Fit-shit">
<span>
{animation ? (
<AiFillLike className="fullLightBlue" />
) : (
<BiLike />
)}
{likes}
</span>
<span onClick={() => dispatch(deletePost(_id))}>
<MdDeleteSweep />
</span>
</div>
</div>
</div>
);
})}
</div>
);
}
};
export default Posts;
The form where i call update and create Post
import React, { useState, useEffect } from "react";
import Filebase from "react-file-base64";
// For the actions
import { useDispatch, useSelector } from "react-redux";
import { createPost, updatePost } from "../actions/posts.js";
import {
Wrapper,
FormContainer,
Data,
DataInput,
SecondDataInput,
FormContainerImg,
FormContainerButtons,
Buttons
} from "./FormStyled.js";
const Form = ({ currentId, setCurrentId }) => {
const [formData, setFormData] = useState({
title: "",
message: "",
image: ""
});
const specificPost = useSelector(state =>
currentId ? state.posts.find(p => p._id === currentId) : null
);
// Sending The Data And Editing The data
const dispatch = useDispatch();
useEffect(() => {
if (specificPost) setFormData(specificPost);
}, [specificPost]);
// Clear Inputs
const clear = () => {
setCurrentId(0);
setFormData({ title: "", message: "", image: "" });
};
const handleSubmit = async e => {
e.preventDefault();
if (currentId === 0) {
dispatch(createPost(formData));
clear();
} else {
dispatch(updatePost(currentId, formData));
clear();
}
};
return (
<Wrapper>
<FormContainer onSubmit={handleSubmit}>
<Data>
<DataInput
name="title"
maxLength="50"
placeholder="Title"
type="text"
value={formData.title}
onChange={e => setFormData({ ...formData, title: e.target.value })}
/>
<SecondDataInput
name="message"
placeholder="Message"
maxLength="300"
value={formData.message}
required
onChange={e =>
setFormData({ ...formData, message: e.target.value })
}
/>
<FormContainerImg>
<Filebase
required
type="file"
multiple={false}
onDone={({ base64 }) =>
setFormData({ ...formData, image: base64 })
}
/>
</FormContainerImg>
<FormContainerButtons>
<Buttons type="submit" create>
{specificPost ? "Edit" : "Create"}
</Buttons>
<Buttons onClick={clear} clear>
Clear
</Buttons>
</FormContainerButtons>
</Data>
</FormContainer>
</Wrapper>
);
};
export default Form;
My actions
import {
GETPOSTS,
CREATEPOST,
DELETEPOST,
UPDATEPOST,
LIKEPOST
} from "../actionTypes/posts.js";
import * as api from "../api/posts.js";
export const getPosts = () => async dispatch => {
try {
const { data } = await api.getPosts();
dispatch({ type: GETPOSTS, payload: data });
} catch (error) {
console.log(error);
}
};
export const createPost = newPost => async dispatch => {
try {
const { data } = await api.createPost(newPost);
dispatch({ type: CREATEPOST, payload: data });
} catch (error) {
console.log(error);
}
};
export const updatePost = (id, updatePost) => async dispatch => {
try {
const { data } = await api.updatePost(id, updatePost);
dispatch({ type: UPDATEPOST, payload: data });
} catch (error) {
console.log(error);
}
};
export const deletePost = id => async dispatch => {
try {
await api.deletePost(id);
dispatch({ type: DELETEPOST, payload: id });
} catch (error) {
console.log(error);
}
};
Redux Part
import {
GETPOSTS,
CREATEPOST,
DELETEPOST,
UPDATEPOST,
LIKEPOST
} from "../actionTypes/posts.js";
const postData = (posts = [], action) => {
switch (action.type) {
case GETPOSTS:
return action.payload;
case CREATEPOST:
return [...posts, action.payload];
case UPDATEPOST:
return posts.map(post =>
action.payload._id === post._id ? action.payload : posts
);
case DELETEPOST:
return posts.filter(post => post._id !== action.payload);
default:
return posts;
}
};
export default postData;
My controllers in the backend
import mongoose from "mongoose";
import infoPost from "../models/posts.js";
// Getting All The Posts
export const getPosts = async (req, res) => {
try {
const Posts = await infoPost.find();
res.status(200).json(Posts);
} catch (error) {
res.status(404).json({ message: error.message });
console.log(error);
}
};
// Creating A Post
export const createPost = async (req, res) => {
const { title, message, image } = req.body;
const newPost = new infoPost({ title, message, image });
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message: error.message });
console.log(error);
}
};
// Update A Post
export const updatePost = async (req, res) => {
const { id } = req.params;
const { title, message, image } = req.body;
if (!mongoose.Types.ObjectId.isValid(id))
return res.status(404).send(`No Post With Id Of ${id}`);
const updatedPost = { title, message, image, _id: id };
await infoPost.findByIdAndUpdate(id, updatedPost, { new: true });
res.json(updatedPost);
};
// Deleting A Post
export const deletePost = async (req, res) => {
const { id } = req.params;
if (!mongoose.Types.ObjectId.isValid(id))
return res
.status(404)
.send(`We Couldnt Found The Post With Id Of ${id} To Delete`);
await infoPost.findByIdAndRemove(id);
res.json(`Post With Id Of ${id} Deleted Succesfully`);
};
// Liking A Post
export const likePost = async (req, res) => {
const { id } = req.params;
if (!mongoose.Types.ObjectId.isValid(id))
return res.status(404).send(`No post with id: ${id}`);
const post = await infoPost.findById(id);
const updatedPost = await infoPost.findByIdAndUpdate(
id,
{ likeCount: post.likeCount + 1 },
{ new: true }
);
res.json(updatedPost);
};
Even though i've been trying to solve this problem for nearly 3.5 hours, i think that the problem might be in my Posts.js part, if you can help me, you're the greatest !
I am trying to make a web application using the Spotify web API.
I used the Spotify auth-server code provided in their GitHub repo for my authorization code https://github.com/spotify/web-api-auth-examples
I followed the instructions here https://medium.com/#jonnykalambay/now-playing-using-spotifys-awesome-api-with-react-7db8173a7b13 to create a simple app that getsCurrentPlayback and displays the songs album art of what is now playing on users Spotify account.
I added a getFeatures function to get the valence of the song.
Right now I want to call the getUsersPlaylists() function from the spotify-web-api.
Once I can get the playlists to call to work I want to iterate through the tracks in the playlist to get each tracks valence. I think once I can get the playlist API call to work I can figure out the rest on my own.
(Help a poor college student out whose teammates don't do anything and who can't get help from the Prof because of COVID)
Thanks so much in advance!
Here is the code for my App.js. I am using REACT
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
class App extends Component {
constructor(){
super();
const params = this.getHashParams();
this.state ={
loggedIn: params.access_token ? true : false,
nowPlaying: {
name: "Not Checked",
image: '',
trackId: "",
valence: ""
},
idParams: {
userId: ""
},
playlistParam: {
playlistName: ""
},
myAccessToken: {
token: ""
}
}
if(params.access_token){
spotifyWebApi.setAccessToken(params.access_token);
}
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
getToken() {
return spotifyWebApi.getAccessToken();
}
// Get user Id of logged in account user.
async getUserId(myToken)
{
const headers = {
Authorization: `Bearer ${myToken}`
};
let userId = '';
const response = await fetch('https://api.spotify.com/v1/me/playlists',
{
headers : headers
}
);
const jsonResponse = await response.json();
if(jsonResponse)
{
userId = jsonResponse.id;
}
return userId;
}
//***HERE IS SOME CODE I HAVE TRIED***
//
// fetch("https://api.spotify.com/v1/me/playlists?limit=1&offset=0", {
// headers: {
// Accept: "application/json",
// Authorization: "Bearer",
// "Content-Type": "application/json"
// }
// })
// fetch("https://api.spotify.com/v1/me/playlists", {
// headers: {
// Authorization: "Bearer {params.access_token}"
// //console.log("Have Gotten The Playlist");
// }
// });
//
// getUserPlaylist() {
// fetch("https://api.spotify.com/v1/me/playlists/", {
// headers: {
// Authorization: "Bearer {this.getToken()}"
// }
// });
//
// console.log("Have Completed It");
//
// }
//********
getNowPlaying() {
spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
this.setState({
nowPlaying: {
name: response.item.name,
image: response.item.album.images[0].url,
trackId: response.item.id
}
});
})
}
getFeatures(){
spotifyWebApi.getAudioFeaturesForTrack(this.state.nowPlaying.trackId)
.then(
function(data){
console.log("Valence of song: ", data.valence);
},
function(err){
console.log(err)
}
);
}
render(){
return (
<div className="App">
<a href="http://localhost:8888">
<button>Login With Spotify</button>
</a>
<div> Now Playing: { this.state.nowPlaying.name } </div>
<div>
<img src={ this.state.nowPlaying.image } style={{width: 100}}/>
</div>
<div>
Track Id: { this.state.nowPlaying.trackId } </div>
<button onClick={() => this.getNowPlaying()}>
Check Now Playing
</button>
<button onClick={() => this.getFeatures()}>
Get Valence
</button>
<button onClick={() => this.getUserPlaylist()}>
Get your Playlists
</button>
<div> Your Selected Playlist : {this.state.playlistParam.playlistName}</div>
<button onClick={() => console.log(this.getUserId(this.params.access_token))}> Get User Id</button>
</div>
);
}
}
export default App;