I'm trying to perform a delete request but I'm facing this error - axios

Front End
import React,{useState, useEffect} from 'react'
import axios from 'axios'
function Renderreview() {
const [renderReview, setRenderReview] = useState([])
useEffect(()=>{
axios.get('/reviews')
.then(res => {
console.log(res)
setRenderReview(res.data)
})
.catch(err => {
console.log(err)
})
},[])
function handleDelete (id){
console.log(renderReview.id)
axios.delete(`/reviews/${renderReview.id}`,)
}
return (
<div className='card1'>
<h2>reviews</h2>
{renderReview.map((renderReview) => {
return(
<div className='renderedreviews'>{renderReview.review}
<button onClick={handleDelete} key={renderReview.review}>Delete</button>
</div>
)
})}
</div>
)
}
export default Renderreview
Back End
def destroy
review =Review.find_by(id: params[:id])
if review.destroy
head :no_content
else
render json: {error: review.errors.messages}, status: 422
end
end
This is the error displaying on my console
DELETE http://localhost:4000/reviews/undefined 500 (Internal Server Error)
Uncaught (in promise)
AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE', config: {…}, request: XMLHttpRequest, …}

Try this, you were not using the correct id:
import React, { useState, useEffect } from 'react'
import axios from 'axios'
function Renderreview() {
const [renderReview, setRenderReview] = useState([])
useEffect(() => {
axios.get('/reviews')
.then(res => {
console.log(res)
setRenderReview(res.data)
})
.catch(err => {
console.log(err)
})
}, [])
function handleDelete(id) {
axios.delete(`/reviews/${id}`,)
}
return (
<div className='card1'>
<h2>reviews</h2>
{renderReview.map((renderReview) => {
return (
<div className='renderedreviews'>{renderReview.review}
<button
onClick={() => {
handleDelete(renderReview.id);
}}
key={renderReview.review}>
Delete
</button>
</div>
)
})}
</div>
)
}
export default Renderreview

Related

Storing session in Browser for express.js (MERN Stack)

I've been trying to store a user's email in the session for my express.js file. But everytime I try something, and call another function, the session remains undefined. I wanted to store it in the browser only without storing each session in the database. Been working on this for weeks now, and I can't seem to find the answer.
server.js file:
import express from 'express';
import cookieParser from 'cookie-parser';
import session from 'express-session';
const app = express();
app.use(cookieParser());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: {
maxAge : 1000 * 60 * 60 * 3, // if 1 day * 24 but since *3 its for 3 hours only
},
}))
app.post('/user/login', (req, res) => {
const loginUser = req.body;
const email = loginUser['email'];
const password = loginUser['password'];
if (!email || !password){
res.status(400).json({success: false, error: "Please provide email and password"});
}
try {
Users.findOne({ email: email }, (err, user) => {
if (password == user['password']){
req.session.user(user['email']);
res.status(200).send(user_email);
} else {
res.status(400).json({success: false, error: "incorrect password"});
}
});
} catch {
}
})
Calling the Login file from the frontend (react js):
import React, { useState } from 'react';
import { Grid, TextField, Button } from '#mui/material';
import "./SignUpLogin.css";
import axios from '../../axios';
import useForm from './useForm';
import { Form } from './useForm';
const initialValues = {
email: '',
password: ''
}
function Login({ modalFunc }) {
const LoginUser = e => {
console.log("INSIDE LOGIN USER");
modalFunc();
e.preventDefault();
axios.post('/user/login', values, {withCredentials: true})
.then(response => {
console.log("in login user");
console.log(response.data);
})
}
const {
values,
setValues,
handleInputChange
} = useForm(initialValues);
return (
<div className="Login">
<Form>
<Grid item>
<TextField
required
variant="outlined"
label="Email"
name="email"
color="secondary"
fullWidth
value={ values.email }
onChange={ handleInputChange }
/>
</Grid>
<Grid item>
<TextField
required
variant="outlined"
label="Password"
name="password"
type="password"
color="secondary"
fullWidth
value={ values.password }
onChange={ handleInputChange }
/>
</Grid>
<Grid item>
<Button
variant="contained"
fullWidth
onClick = { LoginUser }>
Login
</Button>
</Grid>
</Form>
</div>
)
}
export default Login
But when I call server.js again in another get function, session is undefined.
app.get('/user/loggedIn', (req, res) => {
console.log(req.session.user);
user_email = req.session.user;
if (req.session.user) {
Users.findOne({ email: user_email }, (err, user) => {
// console.log("in logged in, in server!!!");
// console.log(user);
res.status(200).send(user);
})
} else {
console.log("no session");
res.status(400);
}
})
Calling app.get('/user/loggedIn') in react.js file:
function Header() {
const [modalOpen, setModalOpen] = useState(false);
const changeModal = () => {
setModalOpen(!modalOpen)
}
const [user, setUser] = useState(null);
useEffect(() => {
// axios.get('/user/loggedIn', {}, {withCredentials: true})
axios.get('/user/loggedIn', {}, {withCredentials: true})
.then(response => {
// console.log("RESPONSE FROM LOGGED IN");
// console.log(response.data);
setUser(response.data);
})
})
server.js
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
})
);
withCredentials should be defined this way
axios.defaults.withCredentials = true;

Cannot access 'getSession' before initialization: How to resolve circular dependencies in SWR/Passport.js?

I'm trying to implement MongoDB, Next.JS and Passport.js, However upon starting my app and while trying to login, I get this 500 status error:
Cannot access 'getSession' before initialization
The preamble for all this is I am using a hook which calls/api/user to see if the req.user has been set by passport thus creating the 'user' below. And if one exists you get access to the other links/routes in the app.
This is the function declaration regarding the getSession function in the session.js file. So I suspect this is what is causing the circular dependencies issue, naturally.
import MongoStore from "connect-mongo";
import nextSession from 'next-session';
import { getMongoClient } from "./mongodb";
const mongoStore = MongoStore.create({
clientPromise: getMongoClient(),
stringify: false,
});
const getSession = nextSession({
store: mongoStore,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 2 * 7 * 24 * 60 * 60, // 2 weeks,
path: "/",
sameSite: "strict",
},
touchAfter: 1 * 7 * 24 * 60 * 60, // 1 week
});
export default function session(req, res, next) {
getSession(req, res);
next();
}
And this is the auth file with the passport file, passport initialization and session.
import passport from '../lib/passport'
import session from '../lib/session'
const auths = [session, passport.initialize(), passport.session()];
export default auths;
/component/Layout
export default function Layout({ children, showFooter = false }) {
const [user, { mutate }] = useCurrentUser();
async function handleLogout() {
axios
.get('/api/logout').then(() => {
mutate({ user: null })
Router.push('/',)
}).catch(err => console.log('err', err))
}
return <>
<div className="shadow bg-base-200 drawer h-screen">
<div className="flex-none hidden lg:block">
<ul className="menu horizontal">
{user
?
<>
<li>
<Link href="/profile">
<a>Profile</a>
</Link>
</li>
<li>
<Link href="/dashboard">
<a>Dashboard</a>
</Link>
</li>
<li>
<a role="button" onClick={handleLogout}>
Logout
</a>
</li>
<li className="avatar">
<div className="rounded-full w-10 h-10 m-1">
<img src="https://i.pravatar.cc/500?img=32" />
</div>
</li></>
:
<>
<li>
<Link href="/login">
<a>Login</a>
</Link>
</li>
<li>
<Link href="/registration">
<a>Register</a>
</Link>
</li>
</>
}
</ul>
</div>
</div>
</>;
}
This is the hook itself:
import useSWR from 'swr';
export const fetcher = (url) => {
try {
return fetch(url).then((res) => {
console.log('res', res)
return res.json()
})
} catch (error) {
console.log('error', error)
}
}
export function useCurrentUser() {
const { data, mutate } = useSWR('/api/user', fetcher);
const user = data?.user;
return [user, { mutate }];
}
export function useUser(id) {
const { data } = useSWR(`/api/users/${id}`, fetcher, {
revalidateOnFocus: false,
});
return data?.user;
}
And this is the api: /api/user:
import nextConnect from 'next-connect'
import auth from '/middleware/auth'
const handler = nextConnect()
handler
.use(auth)
.get((req, res) => {
console.log("req.user ", req.user);
if (req.user) {
res.json({ user: req.user })
} else {
res.json({ user: null })
}
})
export default handler
Also this is my repo
And this is a link to the app on vercel.

Can't get data from api with axios in Nuxt components

<template>
<div id="post">
<p>{{ data }}</p>
</div>
</template>
<script>
export default {
data () {
return {
data: ''
}
},
async asyncData({$axios}) {
const res = await $axios.get('/v1/posts')
.catch( error => {
console.log("response error", error)
return false
})
return {
data: res
}
},
}
</script>
At first, I tried to get the data with the above code, it worked in pages/post.vue but not in components/post.vue.
Then, I realized that I can't use asyncData in the nuxt components and changed the code as follows.
<template>
<div id="post">
<p>{{ data }}</p>
</div>
</template>
<script>
export default {
data () {
return {
data: ''
}
},
mounted () {
this.asyncData()
},
asyncData() {
await axios.get('/v1/posts')
.then(res => {
this.data = res.data
})
},
}
</script>
Then, I got a syntax error "Unexpected reserved word 'await'".
How can I get data via api in Nuxt components?
===================================
I read https://nuxtjs.org/docs/features/data-fetching#accessing-the-fetch-state and changed the code as below.
<script>
export default {
data () {
return {
data: ''
}
},
async fetch() {
this.data = await fetch('/v1/posts')
.then(res => res.json())
},
}
</script>
And now, I'm stacking with another error 'Error in fetch(): SyntaxError: Unexpected token < in JSON at position 0'.
This code worked.
<script>
export default {
data () {
return {
data: '',
}
},
async fetch() {
const res = await this.$axios.get('/v1/posts')
this.data = res.data
},
}
</script>
Glad that found a solution to your issue.
You can even use this.$axios.$get directly if you don't want to have to write .data afterwards.

Delete by field value [MEAN]

I'm learning MEAN stack. I want to perform CRUD operations and I'm using mongoose. I am following this question on stackoverflow. I want to delete a document by specific value. In my case it is an article with a unique articleid which should get deleted. Unknowingly I'm doing some terrible mistake with params. Please correct me.
Sample document in mongodb.
{
_id: objectId("5d77de7ff5ae9e27bd787bd6"),
articleid:"art5678",
title:"Installing JDK 8 in Ubuntu 18.04 and later",
content:"<h2>Step 1: Add repository</h2><p><strong>$ sudo add-apt-repository pp..."
date:"Tue, 10 Sep 2019 17:33:51 GMT"
contributor:"Tanzeel Mirza",
__v:0
}
article.component.html
<div class="row mt-5">
<div class="col-md-4 mb-3" *ngFor="let article of articles;">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">{{article.title}}</h5>
<a (click)="onPress(article.articleid)" class="btn btn-danger">Delete</a>
</div>
</div>
</div>
</div>
(click)="onPress(article.articleid") calls a method in ts file.
article.component.ts
import { Component, OnInit } from '#angular/core';
import { ArticleService } from '../article.service';
#Component({
selector: 'app-articles',
templateUrl: './articles.component.html',
styleUrls: ['./articles.component.css']
})
export class ArticlesComponent implements OnInit {
articles = []
constructor(private _articleService: ArticleService) { }
ngOnInit() {
this._articleService.getEvents()
.subscribe(
res => this.articles = res,
err => console.log(err)
)
}
onPress(id) {
this._articleService.deleteArticle()
.subscribe (
data => {
console.log("hello");
}
);
}
}
I have created a service article.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class ArticleService {
private _deleteUrl = "http://localhost:3000/api/delete/:id";
constructor(private http: HttpClient) { }
getAllArticles() {
...
}
deleteArticle(id) {
return this.http.delete<any>(this._deleteUrl);
}
}
And here is my api.js
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Article = require('../models/article');
const dbstring = ...
mongoose.connect(dbstring, { useNewUrlParser: true }, err => {
...
})
router.delete('/delete/:id', (req, res) => {
let articleData=req.params.id;
console.log(articleData); //Output: {}
console.log('on delete url '+articleData); //Output: on delete url undefined
Article.deleteOne({articleid: articleData}, (error, article) => {
if(error) {
console.log(error)
}
else {
if(!article) {
res.status(401).send('Something went wrong')
}
else {
//res.json(article);
}
}
})
})
module.exports = router;
Ok dont write the code for me, but please at least tell me some study material.
Ok. I did more and more research and figured out the problem. Here are the changes.
api.js
router.delete('/delete/:id', (req, res) => {
let articleId=req.params.id;
Article.deleteOne({articleid: articleId}, (error, article) => {
if(error) {
console.log(error)
}
else {
if(!article) {
...
}
else {
...
}
}
})
})
and article.service.ts
private _deleteUrl = "http://localhost:3000/api/delete";
deleteArticle method should be.
deleteArticle(id) {
return this.http.delete<any>(this._deleteUrl+'/'+id);
}

Redux-Form unable to redirect after onSubmit Success

I would like to redirect to another page after a successful submit in redux-form.
I have tried the follow but the redirect either fails or doesn't do anything
REACT-ROUTER-DOM:
This results is an error 'TypeError: Cannot read property 'push' of undefined'
import { withRouter } from "react-router-dom";
FacilityComplianceEditForm = withRouter(connect(mapStateToProps (FacilityComplianceEditForm));
export default reduxForm({
form: "FacilityComplianceEditForm",
enableReinitialize: true,
keepDirtyOnReinitialize: true,
onSubmitSuccess: (result, dispatch, props) => {
props.history.push('/facilities') }
})(FacilityComplianceEditForm);
REACT-ROUTER-REDUX:
This submits successfully, the data is saved to the DB, but the page does not redirect.
import { push } from "react-router-redux";
export default reduxForm({
form: "FacilityComplianceEditForm",
enableReinitialize: true,
keepDirtyOnReinitialize: true,
onSubmitSuccess: (result, dispatch, props) => { dispatch(push('/facilities')) }
})(FacilityComplianceEditForm);
I also tried onSubmitSuccess: (result, dispatch, props) => dispatch(push('/facilities')) without the {} around dispatch statement but it didn't work
APP.JS to show the path does exist
class App extends Component {
render() {
return (
<div>
<Header />
<div className="container-fluid">
<Switch>
<Route exact path="/facilities" render={() => <FacilitySearch {...this.props} />} />
<Route exact path="/facilities/:id" render={(props) => <FacilityInfo id={props.match.params.id} {...this.props} />} />
<Route exact path="/facilities/compliance/:id" render={(props) => <FacilityComplianceEditForm id={props.match.params.id}{...this.props} />
<Redirect from="/" exact to="/facilities" />
<Redirect to="/not-found" />
</Switch>
</div>
<Footer />
</div>
);
}
}
export default App;
REDUCER:
export const complianceByIdReducer = (state = INTIAL_STATE.compId, action) => {
switch (action.type) {
console.log(state, action)
case "CREATE_NEW_COMPLIANCE":
return {
...state,
compId: action.compCreate
}
default:
return state
}
}
ACTION:
export const createCompliance = (id, compObj) => {
return dispatch => {
axios.post("/api/facilities/compliance/" + id, compObj)
.then(res => { return res.data })
.then(compCreate => {
dispatch(createComplianceSuccess(compCreate));
alert("New compliance created successfully") //this does get triggered
})
}
}
const createComplianceSuccess = compCreate => {
return {
type: "CREATE_NEW_COMPLIANCE",
compCreate: compCreate
}
}
REDIRECT OBJECT RETURNED FROM SUBMIT SUCCESS
STORE
import * as redux from "redux";
import thunk from "redux-thunk";
import {
facilityListReducer,
facilityReducer,
facilityLocationReducer,
facilityHistoricalNameReducer,
facilityComplianceReducer,
complianceByIdReducer
} from "../reducers/FacilityReducers";
import { projectFormsReducer } from "../reducers/FormsReducers";
import { errorReducer } from "../reducers/ErrorReducer";
import { reducer as formReducer } from "redux-form";
export const init = () => {
const reducer = redux.combineReducers({
facilityList: facilityListReducer,
facility: facilityReducer,
facilityLocation: facilityLocationReducer,
historicalNames: facilityHistoricalNameReducer,
facilityCompliance: facilityComplianceReducer,
compId: complianceByIdReducer,
countyList: projectFormsReducer,
errors: errorReducer,
form: formReducer
});
const store = redux.createStore(reducer, redux.applyMiddleware(thunk));
return store;
};
react-router-redux is deprecated so I did not want to add it to my project. I followed this post and made some modification to how routing was set up and it now works.