Changing boolean value in API Mongo MERN React Node - node.js

I am getting error 404 that the API cannot be found. The Boolean in API is "auto_delete". I want to change it to true when this is referenced.
I wrote a button to reference a function that would reference this API but OnClick it will not be able to find this API apparently.
I posted first the front end file with constructor/binding, button, and function. I then put API at bottom.
Any input would help.
//FRONT END
This is the front end with button and function button references to
//CONSTRUCTOR AND BINDING FUNCTION
export default class VideoContent extends Component {
constructor(props) {
super(props);
let video = this.props.video;
let user = this.props.user;
this.state = {
fetchDuration: false,
viewed: false,
subscribed:
user &&
user.hasOwnProperty("follows") &&
user.follows.includes(video.author)
};
this.view = this.view.bind(this);
this.report = this.report.bind(this);
this.reportJ= this.reportJ.bind(this);
}
<Button
disabled={user ? !user.userId : true}
onClick={this.reportJ}
style={{ float: "right", backgroundColor: "purple" }}
>
ReportJ
</Button>
//FUNCTION
reportJ() {
const { video, user } = this.props;
confirmAlert({
title: "Confirm Objectionable Content",
message: "You Sure Fool?",
buttons: [
{
label: "Yes",
onClick: () => {
axios
.post(
inDev
? devAPI.concat("reportJ")
: baseAPI.concat("reportJ"),
{
id: video._id,
update: {
auto_delete: true
}
}
)
.then(res => {
this.setState({ changed: true });
})
.catch(error => {
console.log(error);
});
}
},
{
label: "No",
onClick: () => alert("Nevermind")
}
]
});
}
//SERVER JS File with API below
router.post("/reportJ", (req, res) => {
const { id, update } = req.body;
models.Videos.findById(id, function (err, video) {
video.auto_delete = true;
video.save((err, data) => {
if (err)
return res.json({
success: false,
error: err
});
return res.json({
success: true,
data: data
});
});
});
});

Related

Axios Keeps setting my content type as multipart/form-data; boundary=----WebKitFormBoundary When I have JSON data

I have tried many things including adding the headers to the request. Still does not work. I have looked everywhere and came here as a last resort.
My main.js (routes)
app.post("/timeclock/punchout", async (req, res) => {
let time = moment().unix();
let employeeid = req.body.empid2;
let date = moment().format();
let comments = req.body.comments;
return res.send({ error: false, message: "complete punch" });
});
my liquid file using jQuery and axios
<script>
toast = siiimpleToast.setOptions({
container: 'body',
class: 'siiimpleToast',
position: 'top|right',
margin: 15,
delay: 2,
duration: 3000,
style: {},
})
$("#form").submit(function(event) {
event.preventDefault()
let empid1 = $("#empid").val()
let comments1 = $("#comments").val()
axios.post('/timeclock/punchin', {comments: comments1, empid: empid1}).then(response => {
if(response.data.error == false) {
$("#form").trigger('reset')
toast.success('Punch Successful!')
} else if(response.data.error == true) {
toast.alert(response.data.message)
$("#form").trigger('reset')
}
}, (error) => {
console.log(error)
})
})
$("#form").submit(function(event) {
event.preventDefault()
let empid1 = $("#empid").val()
let commentsout1 = $("#commentsout").val()
axios.post('/timeclock/punchout', {commentsout: commentsout1, empid: empid1}).then(response => {
if(response.data.error == false) {
$("#form").trigger('reset')
toast.success('Punch Successful!')
} else if(response.data.error == true) {
toast.alert(response.data.message)
$("#form").trigger('reset')
}
}, (error) => {
console.log(error)
})
})
any ideas? I read that it automatically detects the content type. But I cant seem to override it.

How can I use switch button to set value to database

Please how can i achieve this!
I have a switch button i'll like to use to control boolean value (true/false) in my MongoDB database
isBanned: {
type: Boolean,
default: false,
},
my button
<b-form-checkbox
v-model="post.isBanned"
switch
#change="isBannedUser($event, post._id)"
>
{{ post.isBanned }})
</b-form-checkbox>
What I expect to happen!
If I toggle the switch checkbox from the frontend (Nuxt), I want isbanned to be set to true and change the default false value in database. If I toggle the same checkbox again next time, I want false value to be sent to the backend and change the db value from true to false and vice versa
<script>
export default {
data() {
return {
post: {
isBanned: null,
},
}
},
methods: {
async isBannedUser(e, id) {
const data = {
isBanned: this.post.isBanned,
}
try {
const response = await this.$axios.$patch(`/api/v1/posts/${id}`, data)
} catch (error) {
console.log(error)
}
},
},
}
</script>
and my API
router.patch('/posts/:id', async (req, res) => {
try {
const banned = await Post.findByIdAndUpdate(req.params.id, req.body)
res.status(201).json({ banned })
} catch (err) {
res.json({
message: err.message,
})
}
})

How to send the page number, page limit in request body from react js Material-UI datatable for cursor pagination

I am trying to achieve cursor pagination on my data table material-ui-datatables.
I am using react js for the front end, express.js backend, and I am using mongo_DB for storage. I want to pass the page number, page limit previous and next as request body from my data table to API and I am using mangoose pagination plugin.
import React, { useState, useEffect } from "react";
import MUIDataTable from "mui-datatables";
import axios from "axios";
import PropagateLoader from "react-spinners/PropagateLoader";
// employee_info
function employee_info() {
let [loading, setLoading] = useState(true);
const [Response, setResponse] = useState([]);
const get_employee_details = () => {
axios
.get(configData.SERVER_URL + "/api/get_employee_info")
.then((res) => {
setResponse(res.data);
setLoading(false);
});
};
useEffect(() => {
const interval = setInterval(() => get_employee_details(), 10000);
return () => {
clearInterval(interval);
};
}, []);
if (loading === true) {
return (
<div style={style}>
<PropagateLoader loading={loading} color={"#36D7B7"} size={30} />
</div>
);
} else {
return EmployeeInfoTable(setResponse);
}
}
//DataTable
function EmployeeInfoTable(value) {
if (
typeof value == "undefined" ||
value == null ||
value.length == null ||
value.length < 0
) {
return <div></div>;
}
const columns = [
{ label: "Employee_ID", name: "employee_id" },
{ label: "Name", name: "name" },
{ label: "Department", name: "department" },
{ label: "Manger", name: "manager" },
];
const data = value.map((item) => {
return [
item.employee_id,
item.name,
item.department,
item.manager,
];
});
const options = {
caseSensitive: true,
responsive: "standard",
selectableRows: "none",
filter: false,
download: false,
print: false,
viewColumns: false,
};
return (
<MUIDataTable
title={"Employee_Details"}
data={data}
columns={columns}
options={options}
/>
);
}
Service API
const MongoPaging = require('mongo-cursor-pagination');
const express = require("express");
const router = express.Router();
router.get('/get_employee_info', async (req, res, next) => {
try {
const result = await MongoPaging.find(db.collection('employee'), {
query: {
employee: req.employee_id
},
paginatedField: 'created',
fields: {
manger: req.manger,
},
limit: req.query.limit,
next: req.query.next,
previous: req.query.previous,
}
res.json(result);
} catch (err) {
next(err);
}
})

Rest API call from REACT APP always return isLoaded: false

import React from 'react';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
items: [],
isLoaded: false
};
}
callAPI() {
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
componetDidMount() {
this.callAPI();
}
render() {
var { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
}
else {
return (
<div className="App">
<ul>
{items.map(item => (
<li key={item.id} >
Id: {item.id} | Name: {item.name}
</li>
))}
</ul>
</div>
);
}
}
}
export default App;
console: no error.
react-developer-tool: returns
state=
{
"error": null,
"items": [],
"isLoaded": false
}
I am very new to REACT and APIs. Please guide me through, what mistake i have done here. I am unable to get the API output.
I am always getting "Loading"
The API does return the json:
{"id":"4570","name":"AR_RESUME_CNC_ROUTING"}
you need to set isLoading to true in your callApi function before every thing else, after that you need to set it false when you get the result or when you catch some error.
callAPI() {
this.setState({
isLoading: true,
});
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoading: false,
items: result.items
});
},
(error) => {
this.setState({
isLoading: false,
error
});
}
)
}
a bit explanation about the code, you always want to show loading when your api call begins, thats why we set isLoading in the beginning of the function, then when we get the result (success or failure, does not matter) the loading state should change to false, because we have at least a result!
also as an extra point you can use try {...} catch {...} finally {...} to have better code style like below:
async callApi() {
try {
this.setState({ isLoading: true })
const result = await fetch("http://localhost:4000/api/process/4570")
const data = await result.json()
this.setState({
items: result.items
});
} catch (e) {
this.setState({ error: e })
} finally {
this.setState({ isLoading: false })
}
}
It looks to me it is some sort of scope issue. You are doing:
this.setState({
isLoaded: true,
items: result.items
});
but you are calling it within the function callback of the fetch promise. So, this is probably referencing the internal Promise object.
I recommend you try this:
callAPI() {
const self = this;
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
self.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
self.setState({
isLoaded: false,
error
});
}
)
}
Re-reference the this, to a new variable (in this case I used self) and try your code there.
Thank you for your response, however the solution which worked for me is as below:
class GetOnlinePosts extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
loading: true,
posts: null,
};
}
async componentDidMount() {
console.log("inside external_json");
const url = "http://localhost:4000/api/process/4570";
const response = await fetch(url);
const data = await response.json();
this.setState({ posts: data, loading: false })
console.log(data);
}
...........

MERN - delete item/row in React Data Table Component

I have a MERN stack application that is modified from a great tutorial I completed. In the original app, transactions were rendered in a list populated from an API call to Mongo Atlas DB. I converted the list to a react-data-table-component and am now trying to figure out how to delete a table row/transaction. The original app had this as part of the transaction component with an onClick button. When I attempt to use the deleteTransaction function, I receive a "TypeError: Cannot read property '_id' of undefined". I can see that the data table renders via the object {transactions}, but cannot figure out why it does not recognize the _id.
Other info: state is managed through the React Context API, with a Router.js and Reducer.js.
TransactionTable.js
import React, { useContext, useEffect } from "react";
// Data table imports
import IconButton from "#material-ui/core/IconButton";
import DeleteIcon from "#material-ui/icons/Delete";
import Card from "#material-ui/core/Card";
import DataTable from "react-data-table-component";
// import transaction component and context provider
import { GlobalContext } from "../context/GlobalState";
// create data table component
export const TransactionTable = () => {
const { transactions, getTransactions, deleteTransaction } = useContext(
GlobalContext
);
// react-data-table-component Columns for back-end data
const columns = [
{
name: "Transaction",
selector: "text",
sortable: true
},
{
name: "Amount",
selector: "amount",
sortable: true,
// conditionally render amount if positive or negative
conditionalCellStyles: [
{
when: row => row.amount > 0,
style: {
color: "green"
}
},
{
when: row => row.amount < 0,
style: {
color: "red"
}
}
]
},
{
// where I'm attempting to pass the transactions prop and apply the deleteTransaction function
// using the delete button that renders in each row
cell: ({ transactions }) => (
<IconButton
aria-label="delete"
color="secondary"
onClick={() => deleteTransaction(transactions._id)}
>
<DeleteIcon />
</IconButton>
)
}
];
useEffect(() => {
getTransactions();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div>
<Card style={{ height: "100%" }} p={2} mx="auto">
<DataTable
title="Transactions"
columns={columns}
data={transactions}
defaultSortField="Transactions"
//actions={actions}
pagination={true}
highlightOnHover={true}
dense={true}
/>
</Card>
</div>
);
};
./controllers/transactions.js - this is where the deleteTransaction function is
const Transaction = require('../models/Transaction');
// #desc Get all transactions
// #route GET /api/v1/transactions
// #access Public
exports.getTransactions = async (req, res, next) => {
try {
const transactions = await Transaction.find();
//const result = result.transaction.toString()
return res.status(200).json({
success: true,
count: transactions.length,
data: transactions
});
} catch (err) {
return res.status(500).json({
success: false,
error: 'Server Error'
});
}
}
// #desc Add transaction
// #route POST /api/v1/transactions
// #access Public
exports.addTransaction = async (req, res, next) => {
try {
const { text, amount } = req.body;
const transaction = await Transaction.create(req.body);
return res.status(201).json({
success: true,
data: transaction
});
} catch (err) {
if(err.name === 'ValidationError') {
const messages = Object.values(err.errors).map(val => val.message);
return res.status(400).json({
success: false,
error: messages
});
} else {
return res.status(500).json({
success: false,
error: 'Server Error'
});
}
}
}
// #desc Delete transaction
// #route DELETE /api/v1/transactions/:id
// #access Public
exports.deleteTransaction = async (req, res, next) => {
try {
const transaction = await Transaction.findById(req.params.id);
if(!transaction) {
return res.status(404).json({
success: false,
error: 'No transaction found'
});
}
await transaction.remove();
return res.status(200).json({
success: true,
data: {}
});
} catch (err) {
return res.status(500).json({
success: false,
error: 'Server Error'
});
}
}
According to the docs https://www.npmjs.com/package/react-data-table-component#custom-cells, each cell is passed an object named row by convention (you can name it to whatever you want)..
This row object should have the _id you need..
// react-data-table-component Columns for back-end data
const columns = [
// ... column items,
{
cell: row => (
<IconButton
aria-label="delete"
color="secondary"
onClick={() => deleteTransaction(row._id)}
>
<DeleteIcon />
</IconButton>
)
}
]
Each row basically represents a single transaction.

Resources