How To Save API DATA Into MYSQL Database - mysql

how can i convert this working mongoose code to a working MYSQL code?, i have a project where i fetch data from online api that updates every 24hours auto, and i need to insert that data information to database mysql but im new to mysql. im using react and node for my project.
import fetch from 'node-fetch';
import mongoose, { mongo } from 'mongoose';
mongoose.connect("mongodb://127.0.0.1:27017/highscore");
const postSchema = new mongoose.Schema({
position: {
type: Number,
required: true
},
id: {
type: Number,
required: true
},
score: {
type: Number,
required: true
},
});
const Post = mongoose.model('Players', postSchema);
async function getPosts() {
const getPlayers = await fetch("http://localhost:3008/api/highscore/players");
const response = await getPlayers.json();
for( let i = 0;i < response.players.length; i++){
const post = new Post({
position: response.players[i]['position'],
id: response.players[i]['id'],
score: response.players[i]['score'],
});
post.save();
}
}
getPosts();
SOME backend code i put together but have no idea where to add the api
app.post('/create', (req, res) => {
const position = req.body.position
const name = req.body.name
const alliance = req.body.alliance
const points = req.body.points
db.query("INSERT INTO stats (position, name, alliance, points) VALUES (?,?,?,?)",
[position, name, alliance, points],
(err, result) => {
if (err) {
console.log(err)
} else {
res.send("Values Inserted")
}
}
);
});
*** COMPLETE CODE THAT FETCHES DATA FROM API ***
const Table = () => {
const [playerName, setPlayerName] = useState([]);
const [playerRank, setPlayerRank] = useState([]);
const [player, setPlayer] = useState([]);
const [perPage, setPerPage] = useState(10);
const [size, setSize] = useState(perPage);
const [current, setCurrent] = useState(1);
const [players, setPlayers] = useState();
const fetchData = () => {
const playerAPI = 'http://localhost:3008/api/players';
const playerRank = 'http://localhost:3008/api/highscore/players';
const getINFOPlayer = axios.get(playerAPI)
const getPlayerRank = axios.get(playerRank)
axios.all([getINFOPlayer, getPlayerRank]).then(
axios.spread((...allData) => {
const allDataPlayer = allData[0].data.players
const getINFOPlayerRank = allData[1].data.players
const newPlayer = allDataPlayer.map(name => {
const pr = getINFOPlayerRank.find(rank => name.id === rank.id)
return {
id: name.id,
name: name.name,
status: name.status,
alliance: name.alliance,
position: pr?.position,
score: pr?.score
}
})
setPlayerName(allDataPlayer)
setPlayerRank(getINFOPlayerRank)
console.log(getINFOPlayerRank)
console.log(newPlayer)
setPlayer(newPlayer)
})
)
}
useEffect(() => {
fetchData()
}, [])

Related

How to import csv to MySQL using ReactJs

I'm trying to upload csv file into mysql workbench, what I'm trying to figure out is when I upload the csv file, the first column of the excel will be the header of the table in workbench.
Front end
const Home = () => {
const [file, setFile] = useState(null);
const handleFileInput = (event) => {
setFile(event.target.files[0]);
};
const handleUpload = async () => {
const formData = new FormData();
formData.append("file", file);
try {
const res = await fetch("http://localhost:5000/api/upload", {
method: "POST",
body: formData,
});
const data = await res.json();
console.log(data);
} catch (error) {
console.error({message:error.message});
}
};
return (
<div>
<input type="file" onChange={handleFileInput} />
<button onClick={handleUpload}>Upload</button>
</div>
)
}
export default Home
index.js
import express from 'express';
import cors from 'cors';
import mysql from 'mysql2/promise';
import csv from 'csv-parser'
const PORT = 5000
const app = express();
app.use(express.json());
app.use(cors())
app.post('/api/upload', async (req, res) => {
const { file } = req.files;
const results = [];
try {
const connection = await mysql.createConnection({
host: "localhost",
user: "root",
password: "admin",
database: "e-learning"
});
fs.createReadStream(file.path)
.pipe(csv())
.on("data", (data) => results.push(data))
.on("end", async () => {
const columns = Object.keys(rows[0]).map(column => `\`${column}\` VARCHAR(255)`);
const tableName = `${filePath}`;
const createTableSql = `CREATE TABLE \`${tableName}\` (${columns.join(", ")})`;
await connection.query(createTableSql);
const insertDataSql = `INSERT INTO \`${tableName}\` (${Object.keys(rows[0]).map(column => `\`${column}\``).join(", ")}) VALUES ?`;
const data = rows.map(row => Object.values(row));
await connection.query(insertDataSql, [data]);
console.log(`Table "${tableName}" created and data inserted successfully.`);
});
} catch (error) {
console.log(error)
}
})
app.listen(PORT, () =>{
console.log(`Listening to port http://localhost:${PORT}`)
})
This is the error i'm receiving

Component responsible to display all my transactions are not updating after submit

I'm using redux toolkit with react and have a basic setup because I'm building a simple expense tracker, so I have two operations: get all transactions and add a new transaction. That's it.
My problem: When I create a new transaction the component responsible for displaying my data does not update and I can only see the changes after refreshing the page.
Below you can see my transactionSlice file:
const initialState = {
transactions: [],
loading: false,
error: null,
}
export const getTransactions = createAsyncThunk(
"transactions/getTransactions",
async () => {
const res = await axios.get('http://localhost:8000/transactions')
return res.data
}
)
export const addTransaction = createAsyncThunk(
"transaction/addTransaction",
async(data) => {
const res = await axios.post('http://localhost:8000/transactions', data);
return res.data
}
)
const transactionsSlice = createSlice({
name: 'transactions',
initialState,
reducers: {},
extraReducers: {
[getTransactions.pending]: (state) => {
state.loading = true;
},
[getTransactions.fulfilled]: (state, {payload}) => {
console.log(payload);
state.loading = false;
state.transactions = payload;
state.error = ''
},
[getTransactions.rejected]: (state) => {
state.loading = false;
state.error = state.error.message;
},
[addTransaction.pending]: (state) => {
state.loading = true;
},
[addTransaction.fulfilled]: (state) => {
state.loading = false;
},
[addTransaction.rejected]: (state) => {
state.loading = false;
state.error = state.error.message;
}
}
});
and here is the code from the component where I'm displaying all transactions
const { transactions, loading } = useSelector(selectAllTransactions);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getTransactions());
}, [dispatch]);
but when I make a post request my state with all transactions doesn't update immediately. I can only see the changes if I update the page and I'm doing it manually. I'm wondering why is this happening if I have useEffect watching for changes?
AddTransaction.js file :
const [transactionName, setTransactionName] = useState('');
const [amount, setAmount] = useState('');
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
const data = {
transactionName,
amount
}
if(transactionName && amount){
dispatch(addTransaction(data));
dispatch(getTransactions());
setTransactionName('')
setAmount('');
}
}
I've tried to google it but it seems my doubt is so silly that I can't even find an answer for that.
Here is my server file:
app.post('/transactions',(req, res) => {
const {transactionName, amount} = req.body;
const query = `INSERT INTO transactions (title, amount)
VALUES ("${transactionName}", "${amount}")`
db.query(query, (err, result) => {
if(err){
console.log(err)
}
res.send(result)
})
});
Am I missing something? Could someone explain to me why the component responsible to display all transactions are not updating after submit, please?
Try executing getTransactions once addTransaction(data) is finished, not at the same time:
const handleSubmit = (e) => {
e.preventDefault();
const data = {
transactionName,
amount
}
if(transactionName && amount){
dispatch(addTransaction(data))
.then(() => {
dispatch(getTransactions())
setTransactionName('')
setAmount('')
}
}
}

Zoom camera inside room and show interior of the room

We are using forge viewer in our web application. We need to zoom camera inside room and show interior of the room.
Please help me to find out that how we can view room interior in forge viewer.
This is a duplicate question on SO, here is an already answered link: https://stackoverflow.com/a/65827867/5747150
You may check out this sample. It’s a revision of my sample forge-viewer-traveling-path. It will move the viewer camera smoothly to the center point of the room’s bounding box.
Demo: https://youtu.be/3MzihDJpi70
Here is the main extension: https://github.com/yiskang/forge-viewer-traveling-path/blob/room-navigation/public/js/MoveToRoomExt.js
/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by Forge Partner Development
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
/////////////////////////////////////////////////////////////////////
(function () {
class RoomListPanel extends Autodesk.Viewing.UI.DockingPanel {
constructor(parent) {
const options = {};
// Height adjustment for scroll container, offset to height of the title bar and footer by default.
if (!options.heightAdjustment)
options.heightAdjustment = 70;
if (!options.marginTop)
options.marginTop = 0;
//options.addFooter = false;
const viewer = parent.viewer;
super(viewer.container, viewer.container.id + 'RoomListPanel', 'Rooms', options);
this.container.classList.add('adn-docking-panel');
this.container.classList.add('adn-room-list-panel');
this.createScrollContainer(options);
this.viewer = viewer;
this.parent = parent;
this.options = options;
this.uiCreated = false;
this.addVisibilityListener(async (show) => {
if (!show) return;
if (!this.uiCreated)
await this.createUI();
});
}
async createUI() {
this.uiCreated = true;
const div = document.createElement('div');
const treeDiv = document.createElement('div');
div.appendChild(treeDiv);
this.treeContainer = treeDiv;
this.scrollContainer.appendChild(div);
const data = await this.getRoomData();
this.buildTree(data);
}
async getRoomData() {
const getRoomDbIds = () => {
return new Promise((resolve, reject) => {
this.viewer.search(
'Revit Rooms',
(dbIds) => resolve(dbIds),
(error) => reject(error),
['Category'],
{ searchHidden: true }
);
});
};
const getPropertiesAsync = (dbId) => {
return new Promise((resolve, reject) => {
this.viewer.getProperties(
dbId,
(result) => resolve(result),
(error) => reject(error),
);
});
}
const data = [];
try {
const roomDbIds = await getRoomDbIds();
if (!roomDbIds || roomDbIds.length <= 0) {
throw new Error('No Rooms found in current model');
}
for (let i = 0; i < roomDbIds.length; i++) {
const dbId = roomDbIds[i];
const propData = await getPropertiesAsync(dbId);
data.push({
id: propData.externalId,
dbId,
name: propData.name
});
}
} catch (ex) {
console.warn(`[RoomListPanel]: ${ex}`);
throw new Error('Failed to extract room data');
}
return data;
}
getBoundingBox(dbId) {
const model = this.viewer.model;
const it = model.getInstanceTree();
const fragList = model.getFragmentList();
let bounds = new THREE.Box3();
it.enumNodeFragments(dbId, (fragId) => {
let box = new THREE.Box3();
fragList.getWorldBounds(fragId, box);
bounds.union(box);
}, true);
return bounds;
}
buildTree(data) {
const nodes = [];
for (let i = 0; i < data.length; i++) {
const node = {
id: data[i].id,
dbId: data[i].dbId,
type: 'spaces',
text: data[i].name
};
nodes.push(node);
}
console.log(nodes);
$(this.treeContainer)
.jstree({
core: {
data: nodes,
multiple: false,
themes: {
icons: false,
name: 'default-dark'
}
},
sort: function (a, b) {
const a1 = this.get_node(a);
const b1 = this.get_node(b);
return (a1.text > b1.text) ? 1 : -1;
},
checkbox: {
keep_selected_style: false,
three_state: false,
deselect_all: true,
cascade: 'none'
},
types: {
spaces: {}
},
plugins: ['types', 'sort', 'wholerow'],
})
.on('changed.jstree', async (e, data) => {
console.log(e, data);
console.log(data.node.original);
const { dbId } = data.node.original;
if (!dbId) return;
const bbox = this.getBoundingBox(dbId);
const center = bbox.center();
const point = new THREE.Vector3(center.x, center.y, bbox.min.z);
this.parent.tweenToPoint(point);
});
}
}
class MoveToRoomExtension extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super(viewer, options);
this.cameraTweenTool = null;
this.uiCreated = false;
}
onToolbarCreated(toolbar) {
const panel = new RoomListPanel(this);
viewer.addPanel(panel);
this.panel = panel;
const roomsPanelButton = new Autodesk.Viewing.UI.Button('room-panel-button');
roomsPanelButton.onClick = () => {
panel.setVisible(!panel.isVisible());
};
roomsPanelButton.setToolTip('Open room list panel');
this.group = new Autodesk.Viewing.UI.ControlGroup('room-nav-tool-group');
this.group.addControl(roomsPanelButton);
toolbar.addControl(this.group);
}
tweenToPoint(point) {
this.viewer.setActiveNavigationTool('bimwalk');
const views = [];
const up = new THREE.Vector3(0, 0, 1);
const currentEye = this.viewer.navigation.getPosition().clone();
const targetPos = point.clone().add(up.clone().multiplyScalar(1.7 * 3.2808399));
const sightDir = point.clone().sub(currentEye).normalize();
const eyeLen = this.viewer.navigation.getEyeVector().length();
const target = targetPos.clone().add(sightDir.clone().multiplyScalar(eyeLen));
views.push({
up: up.toArray(),
eye: targetPos.toArray(),
target: target.toArray()
});
this.processTweens(views);
}
executeTweenPromised(view) {
return new Promise((resolve, reject) => {
const onTweenExecuted = (event) => {
console.log(event);
this.viewer.removeEventListener(
Autodesk.ADN.CameraTweenTool.CAMERA_TWEEN_ANIMATION_COMPLETED_EVENT,
onTweenExecuted
);
resolve();
};
this.viewer.addEventListener(
Autodesk.ADN.CameraTweenTool.CAMERA_TWEEN_ANIMATION_COMPLETED_EVENT,
onTweenExecuted
);
this.cameraTweenTool.tweenCameraTo({ viewport: view });
});
}
processTweens(data) {
//process each promise
//refer to http://jsfiddle.net/jfriend00/h3zaw8u8/
const promisesInSequence = (tasks, callback) => {
const results = [];
return tasks.reduce((p, item) => {
return p.then(() => {
return callback(item).then((data) => {
results.push(data);
return results;
});
});
}, Promise.resolve());
};
//start to process
return promisesInSequence(data, (d) => this.executeTweenPromised(d));
}
async load() {
const loadCSS = (href) => new Promise(function (resolve, reject) {
const el = document.createElement('link');
el.rel = 'stylesheet';
el.href = href;
el.onload = resolve;
el.onerror = reject;
document.head.appendChild(el);
});
await Promise.all([
Autodesk.Viewing.Private.theResourceLoader.loadScript('https://unpkg.com/#tweenjs/tween.js#18.6.4/dist/tween.umd.js', 'TWEEN'),
Autodesk.Viewing.Private.theResourceLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js', '$'),
Autodesk.Viewing.Private.theResourceLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/jstree.min.js', '$'),
loadCSS('https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/themes/default/style.min.css'),
loadCSS('https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/themes/default-dark/style.min.css'),
this.viewer.loadExtension('Autodesk.BimWalk'),
this.viewer.loadExtension('Autodesk.ADN.CameraTweenTool')
]);
this.viewer.setBimWalkToolPopup(false);
this.cameraTweenTool = this.viewer.getExtension('Autodesk.ADN.CameraTweenTool');
console.log('MoveToRoomExtension has been loaded.');
return true;
}
async unload() {
this.viewer.unloadExtension('Autodesk.ADN.CameraTweenTool');
this.viewer.setBimWalkToolPopup(true);
delete this.cameraTweenTool;
this.cameraTweenTool = null;
console.log('MoveToRoomExtension has been unloaded.');
return true;
}
}
Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.ADN.MoveToRoomExtension', MoveToRoomExtension);
})();

Change number of servings on click (React Hooks - API)

I'm working on a recipe site using API from a third party and want to change the number of servings (which is output from the API data) when clicking the + & - button. I tried assigning the output serving amount <Servings>{recipe.servings}</Servings> in a variable and useState to update it but it kept showing errors. I would appreciate any help (preferably using react Hooks). Thanks :)
Here is my code:
const id = 716429;
const apiURL = `https://api.spoonacular.com/recipes/${id}/information`;
const apiKey = "34ac49879bd04719b7a984caaa4006b4";
const imgURL = `https://spoonacular.com/cdn/ingredients_100x100/`;
const {
data: recipe,
error,
isLoading,
} = useFetch(apiURL + "?apiKey=" + apiKey);
const [isChecked, setIsChecked] = useState(true);
const handleChange = () => {
setIsChecked(!isChecked);
};
return (
<Section>
<h2>Ingredients</h2>
<ServingsandUnits>
{recipe && (
<ServingsIncrementer>
<p>Servings: </p>
<Minus />
<Servings>{recipe.servings}</Servings>
<Plus />
</ServingsIncrementer>
)}
<ButtonGroup>
<input
type="checkbox"
id="metric"
name="unit"
checked={isChecked}
onChange={handleChange}
/>
<label htmlFor="male">Metric</label>
</ButtonGroup>
</ServingsandUnits>
</Section>
};
My custom hook is called useFetch:
const useFetch = (url) => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const abortCont = new AbortController();
fetch(url, { signal: abortCont.signal })
.then((res) => {
if (!res.ok) {
// error coming back from server
throw Error("Could not fetch the data for that resource");
}
return res.json();
})
.then((data) => {
setIsLoading(false);
setData(data);
setError(null);
})
.catch((err) => {
if (err.name === "AbortError") {
console.log("Fetch aborted");
} else {
// auto catches network / connection error
setIsLoading(false);
setError(err.message);
}
});
return () => {
abortCont.abort();
};
}, [url]);
return { data, isLoading, error };
};
export default useFetch;

Why am I getting an internal server error when trying to post a new Activity using Design Automation API?

I am creating a simple Node application that posts a new Activity using the Forge Design Automation API. The activity is not supposed to do anything. This is just a test and I plan to delete the Activity right away. When I run this, I get an internal server error. What am I doing wrong?
const config = require(`./utils/Config`);
const CLIENT_ID = config.forge.credentials.client_id;
const CLIENT_SECRET = config.forge.credentials.client_secret;
const autoRefresh = true;
const ForgeSDK = require(`forge-apis`);
const oAuth2TwoLegged = new ForgeSDK.AuthClientTwoLegged(CLIENT_ID, CLIENT_SECRET, [`code:all`], autoRefresh);
const ActivitiesApi = new ForgeSDK.ActivitiesApi();
const activityObject = {
id: `TestActivity`,
instruction: {
CommandLineParameters: null,
Script: ``
},
appPackages: [``],
requiredEngineVersion: `20.1`,
parameters: { InputParameters: [], OutputParameters: [] },
allowedChildProcesses: [],
version: 1,
isPublic: true,
theData: null,
obj: null
};
const activity = new ForgeSDK.Activity(
activityObject.id,
activityObject.instruction,
activityObject.appPackages,
activityObject.requiredEngineVersion,
activityObject.parameters,
activityObject.allowedChildProcesses,
activityObject.version,
activityObject.isPublic,
activityObject.theData,
activityObject.obj
);
const main = async () => {
try {
await oAuth2TwoLegged.authenticate();
createActivity();
} catch (error) {
console.log(error);
}
}
const createActivity = async () => {
try {
await ActivitiesApi.createActivity(activity, oAuth2TwoLegged, oAuth2TwoLegged.getCredentials());
} catch (error) {
console.log(`Creating the activity did not work!`);
console.log(error);
}
};
main();
And here's what I get from logging the error...
Not much there, so I'm at a loss.