How can I get this variable passed to another file? - javascript

I am trying to pass the client value to another file.
I am using express to create a web server that works with my discord bot, and want to do something on a post request to an endpoint.
When the endpoint receives a post request with a user id, the bot should send them a message.
// index.js
const client = new Client(etc etc);
const routes = require('./routes.js');
https.createServer(options, app).listen(PORT, function() {
console.log('Express server listening on port ' + PORT);
});
app.use(bodyParser.json(), routes, limiter);
client.login(token).then(() => {console.info('Logged in.');});
module.exports = { client };
In the index.js file, the server is created, along with various other command handling things that are unrelated.
// routes.js
const express = require('express');
const router = express.Router();
const { invite, topggAuth } = require('./config.json');
const client = require('./index.js');
const vote = require('./events/vote.js');
router.route('/api/tggwh').post((req, res) => {
if (req.header('authorization') === topggAuth) {
vote.execute(client, req.body);
res.status(200).end();
}
else {
console.log('Unauthorized vote request attempt.');
res.send('Unauthorized');
res.status(401).end();
}
});
Routing seems to work fine, it matches the auth header to the key in the config file, then moves on to the vote handler.
// vote.js
const { logUsage } = require('../functions.js');
module.exports = {
name: 'vote', // name, duh
async execute(client, data) { // stuff to do
try {
const targetUser = await client.users.cache.get(data.user);
await targetUser.send('Thank you for voting!');
logUsage({ name: 'vote' });
}
catch (error) {
console.error('Whoops! Something went wrong while thanking a vote.');
console.error(error);
}
},
};
This is where the error comes in.
TypeError: Cannot read properties of undefined (reading 'cache')
at Object.execute (/home/ubuntu/Harold/events/vote.js:7:42)
at /home/ubuntu/Harold/routes.js:43:8
at Layer.handle [as handle_request] (/home/ubuntu/Harold/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ubuntu/Harold/node_modules/express/lib/router/route.js:144:13)
at Route.dispatch (/home/ubuntu/Harold/node_modules/express/lib/router/route.js:114:3)
at Layer.handle [as handle_request] (/home/ubuntu/Harold/node_modules/express/lib/router/layer.js:95:5)
at /home/ubuntu/Harold/node_modules/express/lib/router/index.js:284:15
at Function.process_params (/home/ubuntu/Harold/node_modules/express/lib/router/index.js:346:12)
at next (/home/ubuntu/Harold/node_modules/express/lib/router/index.js:280:10)
at Function.handle (/home/ubuntu/Harold/node_modules/express/lib/router/index.js:175:3)
I think this means that client is passed through, but client.users is not.
How can I pass client through to vote.js after its been called by the post request?

Related

Problem sending json from express to react

I'm learning express and having an issue sending json from my express server to my react app.
On my express server I do an API call to openweathermap API and then send the JSON to react where I pick it up using axios. The problem is, my react app will get the JSON but the data field will be blank, I tried manually sending a JSON using res.json({name:"blank"}) and that sent but the result from my API call won't.
The first code snippet is my Express server and the second snippet is my React app. The last snippet is the error I am getting.
const express = require('express');
const path = require('path');
const app = express();
const fetch = require('node-fetch');
app.get('/test', (req, res) =>
res.send('Welcome to backend this is from node')
);
const port = process.env.PORT || 3001;
app.listen(port);
console.log('App is listening on port ', port);
const apiCall = async () => {
try {
const KEY = fd3909829b4fbfcfcca7c595a56c7632;
const api_res = await fetch(
'api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}'
);
response = await api_res.json();
console.log(response);
return response;
} catch (error) {
console.log('error: ', error);
}
};
app.get('/weather', async (req, res) => {
const data = await apiCall();
res.json(data);
});
import React from 'react';
import './App.css';
import axios from 'axios';
import Weather from './components/weather';
const hitBackend = () => {
axios.get('/weather').then((res) => {
console.log(res);
});
};
function App() {
return (
<div className='App'>
<Weather />
<button onClick={hitBackend}>Send Request!</button>
</div>
);
}
export default App;
error: ReferenceError: fd3909829b4fbfcfcca7c595a56c7632 is not defined
[server] at apiCall (C:\Users\Jalal\Desktop\Coding\React\weather\server\index.js:21:15)
[server] at C:\Users\Jalal\Desktop\Coding\React\weather\server\index.js:34:21
[server] at Layer.handle [as handle_request] (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\layer.js:95:5)
[server] at next (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\route.js:137:13)
[server] at Route.dispatch (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\route.js:112:3)
[server] at Layer.handle [as handle_request] (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\layer.js:95:5)
[server] at C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:281:22
[server] at Function.process_params (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:335:12)
[server] at next (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:275:10)
[server] at expressInit (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\middleware\init.js:40:5)
You need to await your apiCall since it's asynchronous.
app.get('/weather', async (req, res, next) => {
const data = await apiCall();
res.send(data);
});
Your API key variable isn't being set properly
const KEY = fd3909829b4fbfcfcca7c595a56c7632;
Should be
const KEY = "fd3909829b4fbfcfcca7c595a56c7632";
Next you are not handling errors correctly.
Because you are catching the error(s) in the callApi method,
when you are sending the response back to react, you have no way of knowing if the apiCall function succeeded or not.
Also in order to use the ${} notation in a string, you need to use `` instead of " ".
so
'api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}'
Becomes
`https://www.api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}`
This is how I would code it to properly catch errors and also let react know if the request failed.
app.get('/weather', async (req, res) => {
try {
const KEY = "fd3909829b4fbfcfcca7c595a56c7632";
const api_res = await fetch(
`https://www.api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}`
);
response = await api_res.json();
console.log(response);
return res.json(response);;
} catch (error) {
console.log('error: ', error);
return res.status(400).send('error: ' + error.toString());
}
});
The main problem on your express app is that you are not awaiting the apiCall method on your route. So, the function is executing but not awaiting the async code that you had over there.
So, you will need to await that, like this:
app.get("/weather", async (req, res, next) => {
const weather = await apiCall()
res.send(weather);
});
Also, I see that you are using fetch for getting the API response from weather, but not requiring any module. Fetch is a browser API. You can install node-fetch or use axios for this purpose.

how to respond with MYSQL select result using node js using JSON format

I am trying to build a restful API using nodejs with MySQL and Express. I started with simplest code that retrieve all records from a table but I am facing an error when sending query result to client using res.send() or res.json()
but I am getting this error message:
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Query'
| property '_timer' -> object with constructor 'Timer'
--- property '_object' closes the circle
at JSON.stringify ()
at stringify (C:\Users\Developers\Desktop\ex\node_modules\express\lib\response.js:1123:12)
at ServerResponse.json (C:\Users\Developers\Desktop\ex\node_modules\express\lib\response.js:260:14)
at ServerResponse.send (C:\Users\Developers\Desktop\ex\node_modules\express\lib\response.js:158:21)
at C:\Users\Developers\Desktop\ex\index.js:12:9
at Layer.handle [as handle_request] (C:\Users\Developers\Desktop\ex\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Developers\Desktop\ex\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Developers\Desktop\ex\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Developers\Desktop\ex\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Developers\Desktop\ex\node_modules\express\lib\router\index.js:281:22
this is my index.js code
const express=require('express');
const bodyParser=require('body-parser');
const dbObject=require('./models/db')
const app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.get("/",(req,res)=>{
;
res.send(dbObject.getAll());
})
app.listen(5200,()=>{
console.log("server started...")
});
and this is db.js where i execute the SQL command
module.exports={
getAll:()=>{
var getData=()=>connection.query("select * from currencies",(err,result)=>{
if(err)
throw err;
console.log(result);
return result;
})
return getData();
}
}
this is what I got when i print the result in console
server started...
connected to db successful
[
RowDataPacket { cur_id: 1, cur_name: 'Dollar', cur_letters: 'USD' },
RowDataPacket {
cur_id: 2,
cur_name: 'Saudi Ryal',
cur_letters: 'SAR'
}
]
The problem is in your code for getAll. You're returning a value inside of a callback which doesn't actually return the value for your getAll function call. The actual value that gets returned by getAll is a mysql Query object.
The accessing of the database also happens asynchronously and so the only way to return the data in your express handler is to make the handler asynchronous as well so you can await the data or to call res.send inside of the callback for your query.
I'd suggest returning a promise in your getAll function
// db.js
module.exports = {
getAll(){
return new Promise((resolve, reject) => {
connection.query("select * from currencies", (err, result) => {
if(err){
// The equivalent of throwing the error
reject(err);
} else {
// The equivalent of returning a value for getAll
resolve(result);
}
})
});
}
}
and then you can set up your route handler and use the await keyword to wait for the query to resolve before sending something to the client.
// index.js
app.get("/", async (req,res)=>{
const data = await dbObject.getAll();
res.json(data);
});

Getting error while POST request with JSON

This is my server.js file code . I am trying to push the JSON content in the user object , but i am getting following error. Please tell me where i am going wrong.
const express = require('express')
const app = express()
const bcrypt = require('bcrypt')
const bodyParser = require('body-parser')
app.use(express.json())
const users = []
app.get('/users', (req, res) => {
JSON.stringify(users)
res.json(users)
})
app.post('/users', (req, res) => {
const user = {
name: req.body.name,
password: req.body.password
}
users.push(user)
res.status(201).send()
})
app.listen(3000, console.log("server started"));
I used an extension in VS code called REST client.
GET http: //localhost:3000/users
#####
POST http: //localhost:3000/users
Content-Type: application/json
{
"name": "Tanay",
"password": "password"
}
When I'm firing POST request it shows the error - SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at parse (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\body-parser\lib\types\json.js:89:19)
at C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:224:16)
at done (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:273:7)
at IncomingMessage.emit (events.js:322:22)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
Can be something wrong with the user variable. Can you check this:
const user={'name':req.body.name,'password':req.body.password}
Update
I tried out:
var data = [];
const user={'name':"Deshan",'password':"password"}
data.push(user);
console.log(data);
And the result was as follow:
[ { name: 'Deshan', password: 'password' } ]
So it maybe a problem with the request data.

my express endpoint route with mysql logs an error: connect ECONNREFUSED 127.0.0.1

I'm building a web app for a bootcamp. I'm using express and mysql. I'm routing a get request to an endpoint. The route should query my mysql database table to select all. I'm expecting to send the result to the chrome page. Instead I get this error:
Error: connect ECONNREFUSED 127.0.0.1:8211
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14)
--------------------
at Protocol._enqueue (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at Connection.connect (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/mysql/lib/Connection.js:119:18)
at Connection._implyConnect (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/mysql/lib/Connection.js:457:10)
at Connection.query (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/mysql/lib/Connection.js:199:8)
at Object.getAllUsers (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/database/index.js:17:14)
at /Users/cnebs/Documents/HRATX/hratx42-fullstack-review/server/index.js:22:6
at Layer.handle [as handle_request] (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/cnebs/Documents/HRATX/hratx42-fullstack-review/node_modules/express/lib/router/route.js:112:3) {
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 8211,
fatal: true
}
I'm able to query the database in terminal. I'm able to send text to the page on chrome through express. I've built a database and table. I haven't used the api for my project to populate the table yet. My console is logging the error through a function in my database index which I've imported to express to be used in the get route.
Here is the database index:
const mysql = require('mysql');
const connection = mysql.createConnection({
host: "127.0.0.1",
user: "root",
password: "password",
database: "github",
port: 8211
});
const test = () => {
connection.query("DESCRIBE git_repos", (err, res) => {
console.log('selection: ', res)
})
}
const getAllUsers = cb => {
connection.query(`select * from todos`, (err, res) => {
if (err) {
console.log("error in getAllUsers: ", err);
cb(err);
} else {
cb(null, res);
}
});
}
module.exports = { test, getAllUsers }
Here is the server index:
const express = require('express');
const db = require('../database')
let app = express();
app.use(express.static(__dirname + '/../client/dist'));
app.get('/repos', function (req, res) {
// TODO - your code here!
// This route should send back the top 25 repos
db.getAllUsers((err, result) => {
if (err) {
console.error(err)
res.status(404).end();
} else {
console.log('Getting')
res.send(result)
}
})
});
let port = 1128;
app.listen(port, function() {
console.log(`listening on port ${port}`);
});
I expect to see any result at all from my query delivered to the page from the res.send.
Instead, I see that the localhost page can't be found and the err response above in my server terminal.
You aren't able to directly choose the port for your database server in the createConnection(). Remove the port property and it will function.

async/await stuck forever

Writing a webapp that uses async/await but got stuck where the line var r1 = await fetch(url).then((r) => r.text()) appears to be handing forever. My web server listening on port 80 didn't even receive the request.
const fetch = require ('fetch-node')
const express = require('express');
const app = express();
var savedResolve;
app.listen(8079, '127.0.0.1', function() {
console.log('listening on 8079')
})
app.get('/*', async function (req, res) {
console.log(req.path)
res.setHeader('Content-Type', 'text/html');
await task()
res.send('Done')
})
async function task() {
console.log("starting..")
var url = "http://localhost/prod/te.php";
var r1 = await fetch(url).then((r) => r.text())
console.log(r1)
return "done"
}
Any ideas? Thanks in advance!
Update1
Thanks to suggestion by #deryck, add try and catch around the line of fetch call, got the following error instead
TypeError: Cannot read property 'render' of undefined
at module.exports (/Users/jsmith/learn/node/node_modules/hooks-node/hooks-node.js:8:11)
at module.exports (/Users/jsmith/learn/node/node_modules/fetch-node/fetch-node.js:17:1)
at task (/Users/jsmith/learn/node/te4b.js:22:18)
at /Users/jsmith/learn/node/te4b.js:13:8
at Layer.handle [as handle_request] (/Users/jsmith/learn/node/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/jsmith/learn/node/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/jsmith/learn/node/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/jsmith/learn/node/node_modules/express/lib/router/layer.js:95:5)
at /Users/jsmith/learn/node/node_modules/express/lib/router/index.js:281:22
at param (/Users/jsmith/learn/node/node_modules/express/lib/router/index.js:354:14)
node-fetch and fetch-node are two differnt libraries.
And based on the shown code node-fetch is the library that should be used.

Categories

Resources