MongoDB update user - node.js

I'm trying to update user, but it gives me this error:
I can't find any solution of it. Tried to use different UserSchema methods, like findOneAndUpdate, updateOne, but nothing helps..
This is my mainController:
updateUser: async (req, res) => {
try {
const updatedUser = await UserSchema.updateOne({ secret: req.params.secret }, { $set: req.body });
res.status(200).json(updatedUser);
} catch (error) {
res.status(400).json({ message: error.message });
}
},
This is my router:
mainRouter.post('/update/:secret', updateUser)
This is where I'm posting in front end:
import React, { useState, useEffect } from 'react';
import { Link, useParams, useNavigate } from 'react-router-dom';
import Toolbar from '../components/Toolbar';
import { get, post } from '../helper/helper';
export default function TestPage() {
const [current, setCurrent] = useState('')
const [index, setIndex] = useState(0);
const [allUsers, getAllUsers] = useState([])
const secret = window.localStorage.getItem('secret')
const nav = useNavigate()
useEffect(() => {
async function currentUser() {
const resp = get(`user/${secret}`)
setCurrent(resp)
}
currentUser()
}, [])
useEffect(() => {
async function fetchUsers() {
const resp = await get('api')
getAllUsers(resp)
}
fetchUsers()
}, [])
allUsers.filter(user => user.secret !== secret)
console.log(index)
const currentUser = allUsers[index];
async function postLiked() {
const likedObj = {
liked: [currentUser]
}
const likesObj = {
likes: [current]
}
await post(`update/${current.secret}`, likedObj)
await post(`update/${currentUser.secret}`, likesObj)
}
async function postDislike() {
const dislikeObj = {
disliked: [currentUser]
}
await post(`update/${current.secret}`, dislikeObj)
}
return (
<div className='home__page'>
<Toolbar />
<div className="home__users">
<div className='single__user'>
<img src={currentUser && currentUser.image[0]} alt="" />
<h3>{currentUser && `${currentUser.firstName} ${currentUser.lastName}`}</h3>
<h4>{currentUser && currentUser.gender}</h4>
<button onClick={() => { setIndex(index + 1); postDislike(); nav(`/${currentUser.secret}`) }}>Dislike</button>
<button onClick={() => { setIndex(index + 1); postLiked(); nav(`/${currentUser.secret}`) }}>Like</button>
</div>
</div>
<footer className='footer'>
<p>All rights reserved by Cartoon Match organization. To read more about our policy <Link to='/policy'>click here</Link>. </p>
</footer>
</div>
)
}
helper.js:
export const get = async (url) => {
const options = {
method: 'GET',
headers: {
'Content-type': 'application/json',
},
};
const response = await fetch(`http://localhost:4000/${url}`, options);
if (response.ok) {
const dataFromGetRequest = await response.json();
return dataFromGetRequest;
}
};
export const post = async (body, url) => {
const options = {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(body),
};
const response = await fetch(`http://localhost:4000/${url}`, options);
if (response.ok) {
const dataFromPostRequest = await response.json();
return dataFromPostRequest;
}
};
export const put = async (body, url) => {
const options = {
method: 'PUT',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(body),
};
const response = await fetch(`http://localhost:4000/${url}`, options);
if (response.ok) {
const dataFromPostRequest = await response.json();
return dataFromPostRequest;
}
};

If react and node.js run on different port, Browser refuse to connect.
Add this line after const app = express();
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST,OPTIONS, GET, PUT, PATCH, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization,token-type");
next();
});

Related

TypeError: data.outputs is undefined

i have added my detect face Clarifai API key to the backend so that the autorization code(API) won't show up in the console, and now It stopped detecting all the faces
I'm getting the below error message in the console
TypeError: data.outputs is undefined
calculateFaceLocation App.js:49
onButtonSubmit App.js:95
promise callback*./src/App.js/</App/this.onButtonSubmit App.js:72
React 23
js index.js:8
js main.chunk.js:2298
Webpack 7
see backend below
const express = require('express');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt-nodejs');
const cors = require('cors');
const knex = require('knex');
const register = require('./controllers/register');
const signin = require('./controllers/signin');
const profile = require('./controllers/profile');
const image = require('./controllers/image');
const db = knex({
client: 'pg',
connection: {
host : '127.0.0.1',
user : 'postgres',
port: 5432,
password : 'Moshe6700',
database : 'smart-brain'
}
});
const app = express();
app.use(bodyParser.json())
app.use(cors())
app.get('/', (req, res) => {res.send(database.users) })
app.post('/signin', (req, res) => {signin.handleSignin(req, res, db, bcrypt)})
app.post('/register', (req, res) => {register.handleRegister(req, res, db, bcrypt)})
app.get('/profile/:id', (req, res) => {profile.handleProfile(req, res, db)})
app.put('/image', (req, res) => {image.handleImage(req, res, db)})
app.post('/imageurl', (req, res) => {image.handleApiCall(req, res)})
app.listen(3001, () => {
console.log('app is running on port 3001')
})
image.js in the backend
const Clarifai = require('clarifai');
const app = new Clarifai.App({
apiKey: '489560069986431e89aa152fe709ba94'
});
const handleApiCall = (req, res) => {
app.models
.predict(Clarifai.FACE_DETECT_MODEL, req.body.input)
.then(data => {
res.json(data);
})
.catch(err => res.status(400).json('unable to work with API'))
}
const handleImage = (req, res, db) => {
const { id } = req.body;
db('users').where('id', '=', id)
.increment('entries', 1)
.returning('entries')
.then(entries => {
res.json(entries[0].entries)
})
.catch(err => res.status(400).json('unable to get entries'))
}
module.exports = {
handleImage:handleImage,
handleApiCall:handleApiCall
}
frontend code
import React, {Component} from 'react';
import Navigation from './components/Navigation/Navigation';
import Logo from './components/Logo/Logo';
import ImageLinkForm from './components/ImageLinkForm/ImageLinkForm';
import FaceRecognition from './components/FaceRecognition/FaceRecognition';
import Rank from './components/Rank/Rank';
import Signin from './components/Signin/Signin';
import Register from './components/Register/Register';
import './App.css';
const intialState = {
input: '',
imageUrl: '',
box: {},
route: 'signin',
isSignedIn: false,
user: {
id: '',
name: '',
email: '',
entries: 0,
joined: ''
}
}
class App extends Component {
constructor() {
super();
this.state = intialState
}
loadUser = (data) => {
this.setState({user: {
id: data.id,
name: data.name,
email: data.email,
entries: data.entries,
joined: data.joined
}})
}
calculateFaceLocation =(data) => {
console.log(data)
const clarifaiFace = data.outputs[0].data.regions[0].region_info.bounding_box;
const image = document.getElementById('inputimage');
const width = Number(image.width);
const height = Number(image.height);
return {
leftCol: clarifaiFace.left_col * width,
topRow: clarifaiFace.top_row * height,
rightCol: width - clarifaiFace.right_col * width,
bottomRow: height - clarifaiFace.bottom_row * height,
}
}
displayFaceBox = (box) => {
console.log(box)
this.setState({box: box});
}
onInputChange = (event) => {
this.setState({input: event.target.value})
}
onButtonSubmit = () => {
this.setState({imageUrl: this.state.input})
fetch('http://localhost:3001/imageurl', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
input: this.state.input
})
})
.then(response => response.json())
.then( response => {
if (response) {
fetch('http://localhost:3001/image', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
id: this.state.user.id
})
})
.then(response => response.json())
.then(count => {
this.setState(Object.assign(this.state.user, { entries: count}))
})
.catch(console.log)
}
this.displayFaceBox(this.calculateFaceLocation(response))
})
.catch(err => console.log(err));
}
onRouteChange = (route) => {
if (route === 'signout') {
this.setState(intialState)
} else if (route === 'home') {
this.setState({isSignedIn: true})
}
this.setState({route:route});
}
render() {
return (
<div className="App">
<Navigation isSignedIn={this.state.isSignedIn} onRouteChange={this.onRouteChange} />
{ this.state.route === 'home'
? <div>
<Logo />
<Rank
name={this.state.user.name}
entries={this.state.user.entries}/>
<ImageLinkForm
onInputChange={this.onInputChange}
onButtonSubmit={this.onButtonSubmit} />
<FaceRecognition box={this.state.box} imageUrl={this.state.imageUrl}/>
</div>
:(
this.state.route === 'signin'
?<Signin loadUser={this.loadUser} onRouteChange={this.onRouteChange} />
:<Register loadUser={this.loadUser} onRouteChange={this.onRouteChange} />
)
}
</div>
);
}
}
export default App;
Any ideas why this is happening?
Your stackstace is quite clear
TypeError: data.outputs is undefined
calculateFaceLocation App.js:49
data.outputs that is provided to calculateFaceLocation function seems to be undefined
From what I see you only call this function in your onButtonSubmit which mean that
fetch('http://localhost:3001/imageurl', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
input: this.state.input
})
})
.then(response => response.json())
.then( response => {
// response here is probably not as you expect
...
this.displayFaceBox(this.calculateFaceLocation(response))
});
=> Probably that the data that is sent back from your back endpoint is malformatted

POST http://localhost:8080/todo net::ERR_ABORTED 400 (Bad Request), how do I fix this?

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);
});
}, []);

Unable to make post request to server : 404 error

I am trying to send data to my server but I think I am not sending it correctly.
I get the following error in the backend
Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>), here is my front call with fetch:
import { CardElement, useElements, useStripe } from "#stripe/react-stripe-js"
import * as styles from './Checkout.module.scss'
export default function Checkout({ setCheckout, currentPackage }) {
const stripe = useStripe();
const elements = useElements();
const pay = async () => {
try {
const response = await fetch("http://localhost:5001/api/user/pay/coins", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: {
"userId": '61b1bfe057e557000845fc78',
"coins": currentPackage
}
}
);
const data = await response.json();
const cardElement = elements.getElement(CardElement);
const confirmPayment = await stripe.confirmCardPayment(
data.clientSecret,
{ payment_method: { card: cardElement } }
);
const { paymentIntent } = confirmPayment;
if (paymentIntent.status === "succeeded") alert(`Payment successful!`);
else alert(`Payment failed!`);
} catch (err) {
alert("There was an error in payment:", err);
}
};
return (
<div className={styles.modal_container}>
<div className={styles.modal_box}>
<div className={styles.modal_header}>
<p className={styles.modal_title}>Payment</p>
</svg>
</div>
<div className={styles.modal_body}>
<div className={styles.card}>
<CardElement />
<button onClick={() => pay()}>Buy</button>
</div>
</div>
</div>
</div>
)
}
And this is my back that shows the message I told you about that is running on Express
const router = require("express").Router();
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const User = require("../models/User");
router.post("/coins/", async (req, res) => {
const userId = req.body.userId;
const coins = req.body.coins;
var amount;
switch (coins) {
case 1000:
amount = amount + 9999;
break;
case 5000:
amount = amount + 29999;
break;
}
try {
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: "usd",
payment_method_types: ["card"],
metadata: {
name: "value",
},
});
const clientSecret = paymentIntent.client_secret;
await User.findOneAndUpdate({ _id: userId }, { $inc: { coins: coins } });
res.json({ clientSecret, message: "Payment Initiated" });
} catch (err) {
console.error(err);
res.status(500).json({ message: "Internal server error" });
}
});
module.exports = router;
Kindly help me rectify the mistakes.
As explained here, you should stringify your request body payload on the client-side:
const response = await fetch("http://localhost:5001/api/user/pay/coins", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"userId": '61b1bfe057e557000845fc78',
"coins": currentPackage
})
});

React-Admin Pagination didn't work properly?

first of all take a look to the problem :pagination problem
I'm using react-admin for the first time, so i just was getting started and creating some small projects to practice before i integrate it to my real project.
so i'm using react for the front-end and nodejs with express middleware for the backend.
as far i know react-admin has a dataprovider so i created dataprovider.js file:
import { fetchUtils } from 'react-admin';
import { stringify } from 'query-string';
const apiUrl = 'http://localhost:5000';
const httpClient = fetchUtils.fetchJson;
export default {
getList: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
httpClient(url).then(({ headers, json }) => {
console.log(headers.get('content-range'))
console.log(json)
});
return httpClient(url).then(({ headers, json }) => ({
data: json.map((resource)=>({...resource, id:resource._id})),
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
},
getOne: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`).then(({ json }) => ({
data: json,
})),
getMany: (resource, params) => {
const query = {
filter: JSON.stringify({ id: params.ids }),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
return httpClient(url).then(({ json }) => ({ data: json }));
},
getManyReference: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify({
...params.filter,
[params.target]: params.id,
}),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => ({
data: json,
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
},
update: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`, {
method: 'PUT',
body: JSON.stringify(params.data),
}).then(({ json }) => ({ data: json })),
updateMany: (resource, params) => {
const query = {
filter: JSON.stringify({ id: params.ids}),
};
return httpClient(`${apiUrl}/${resource}?${stringify(query)}`, {
method: 'PUT',
body: JSON.stringify(params.data),
}).then(({ json }) => ({ data: json }));
},
create: (resource, params) =>
httpClient(`${apiUrl}/${resource}`, {
method: 'POST',
body: JSON.stringify(params.data),
}).then(({ json }) => ({
data: { ...params.data, id: json.id },
})),
delete: (resource, params) =>
httpClient(`${apiUrl}/${resource}/${params.id}`, {
method: 'DELETE',
}).then(({ json }) => ({ data: json })),
deleteMany: (resource, params) => {
const query = {
filter: JSON.stringify({ id: params.ids}),
};
return httpClient(`${apiUrl}/${resource}?${stringify(query)}`, {
method: 'DELETE',
}).then(({ json }) => ({ data: json }));
}
};
and the App component which contains Admin:
import * as React from "react";
import { Admin, Resource } from 'react-admin';
import dataProvider from './DataProvider'
import { Products } from "./Products";
const App=()=> {
return (
<div className="App">
<Admin dataProvider={dataProvider}>
<Resource name='Products' list={Products} />
</Admin>
</div>
);
}
export default App;
and this is the products component:
import * as React from "react";
import { List, Datagrid, TextField, EditButton } from 'react-admin';
export const Products = props => (
<List {...props}>
<Datagrid rowClick="edit">
<TextField source='id'/>
<TextField source="Title" />
<TextField source='Brand'/>
<EditButton />
</Datagrid>
</List>
);
--------------------Backend:Nodejs -- expressjs ------------------------------------
and this is my simple server that return products from the database:
const express = require('express')
const app = express()
const port = 5000
var MongoClient = require("mongodb").MongoClient;
const { ObjectId } = require("mongodb"); // or ObjectID
var url = "mongodb://localhost:27017/storedz";
var db;
var storedz;
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", req.header("Origin"));
res.header("Access-Control-Allow-Credentials", true);
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.header("Access-Control-Expose-Headers", "Content-Range");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
MongoClient.connect(url, function (err, database) {
if (err) throw err;
db = database;
storedz = db.db("storedz");
});
app.get('/Products',(req, res) => {
storedz
.collection("products")
.find({})
.toArray((err, result) => {
if (err) {
return res.header(400).json("something went wrong");
}
res.header("Content-Range", `getProducts 0-4/${result.length}`);
console.log(result.length)
res.send(result);
});
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
so everything is working i mean i'm getting all the products, and i u res.header("Content-Range", Products 0-4/${result.length}); because react-admin need it to make the pagination.
so guys if i'm missing something here please correct me and give the right path so i can move to my next step.
thank you.

React Native app Cannot Fetch data from Firestore using Api NodeJS

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;
}
};
};

Resources