NodeJS killed when react-native app is closed - node.js

Actually i'm new to react and node and i was trying to make a simple NodeJS server which return some data from MySQL Database but i'm having some issues with the back-end part.
Actually i've installed NodeJS in another computer and followed this guide to deploy it.
Then in my React-Native app i just do simple fetch call to the NodeJS with the ip of the computer where the back-end part is installed till here all work fine and even from my personal computer i can get the data from NodeJS server but i face the issue when after loading data in React-App i kill that app and then i reopen it after that seems the server just die and i have to restart it with command 'node myfile.js'
After killing the app, NodeJS server is impossible to reach from any device and in browser after some minutes of load just return 'PAGE DOESN'T WORK ERR_EMPTY_RESPONSE'
Here is routes.js file located in another PC
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'block',
database : 'mydb'
});
// Starting our app.
const app = express();
// Creating a GET route that returns data from the 'users' table.
app.get('/prenotazioni', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query("SELECT Data, Importo_Doc FROM tabella_pagamenti", function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('Vai su http://localhost:3000/prenotazioni per vedere i dati.');
});
While method in my react-app where i call fetch is the following
GetData = () => {
return fetch('http://192.168.100.160:3000/prenotazioni')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}

Related

can't read properties for SET/GET in redis and node.js

I just start to explore redis. I want to cache some data using redis. I set up redis connection in the server.ts file and export it from there. Import it in my controller function and try to use set and get but this error comes for both get and set.
TypeError: Cannot read properties of undefined (reading 'get')
//sever.js---> redis connection part
export const client = redis.createClient({
url: "redis://127.0.0.1:6379",
});
client.connect();
client.on("error", (err) => console.log("Redis Client Error", err));
const app: Application = express();
//controller
import { client } from "../server";
const allProjects = async (req: Request, res: Response): Promise<void> => {
const cachedProjects = await client.get("projects");
if (cachedProjects) {
res.status(200).json(JSON.parse(cachedProjects));
}
const projects = await Projects.find({});
if (!projects) {
res.status(400).send("No projects found");
throw new Error("No projects found");
}
await client.set("projects", JSON.stringify(projects));
res.status(200).json(projects);
};
My Redis server is running and I can use set/get using redis cli. I make a mistake somewhere but can't find it.
I am using Node.js, Express.js and Typescript
This error is most likely because client is undefined. This suggests that your import from server.js isn't doing what you think it is. This could be because server.js is special from a Node.js point of view as it's the default file that loads when you run npm start. Might be better to put that code in its own file.
To test this, try doing a .get and .set in server.js after your connection is established and see if that works. If so, you've proved you can talk to Redis. The rest is debugging.
Also, you might want to refer to the example code on the Node Redis Github repo. I've added it here for your convenience:
import { createClient } from 'redis';
const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
await client.set('key', 'value');
const value = await client.get('key');
Note that Alexey is right that you need to await the establishment of a connection. You should also add the error handler before doing so. That way if establishing a connection fails, you'll know about it.
Wait until client connected to the server and then export it
//sever.js---> redis connection part
const client = await redis.createClient({
url: "redis://127.0.0.1:6379",
});
await client.connect();
client.on("error", (err) => console.log("Redis Client Error", err));
const app: Application = express();
export client
I find the solution. Actually, I write the Redis server connection code in the wrong place. It should be after all path. Then it works fine.
app.use("/api/v1/uploads", imageUpload);
app.use("/api/v1/forgetPassword", forgetPassword);
app.use("/api/v1/resetPassword", resetPassword);
app.use("/uploads", express.static(path.join(dirname, "/uploads")));
client.connect();
client.on("connected", ()=> console.log("Redis connected"))
client.on("error", (err) => console.log("Redis Client Error", err));
app.use(notFound);
var server = app.listen(process.env.PORT || 3001, () =>
console.log(`Listening on port ${process.env.PORT}`)
);

Express not fetching data from postgres database. No errors displayed

I found someone with the exact same problem as me, but it had no answers. So I am copy-pasting this guy's question, hope someone can help me:
This is a difficult question for me to ask because I'm not truly sure what the issue is.
I have an Express JS server for routing and Node Postgres (PG) for the pool.
When I either go directly to localhost or use POSTMAN to test the routes there is no response except a simple loading screen. With POSTMAN, it gets stuck like so:
POSTMAN sending request...
Or for localhost it simply stays buffering/loading.
I am following this video on how to deploy a PERN app to Heroku. However, even after cloning the repo and updating all the packages within I cannot fetch data from my database (I am using PostgreSQL). I have updated all the database login information so it's not that.
Below is my code:
Server:
const express = require("express");
const app = express();
const cors = require("cors");
const pool = require("./db");
app.use(cors());
app.use(express.json());
app.get("/todos", async (req, res) => {
try {
console.log("route hit"); // this msg gets displayed when i send a req
const allTodos = await pool.query("SELECT * FROM todo");
console.log("route hit again"); // this msg does not gets displayed when i send a req
res.json(todo.rows[0]);
} catch (err) {
console.error(err.message);
}
});
app.listen(5000, () => {
console.log("server has started on port 5000");
});
Pool
const Pool = require("pg").Pool;
const pool = new Pool({
user: "postgres",
password: "postgres",
host: "localhost",
port: 5432,
database: "perntodo"
});
module.exports = pool;
All pool information is correct.
I have checked my database and there are active tables and data.
Again, there are no errors displayed so it's super hard for me to diagnose the problem.
Try exporting pool like in the docs:
module.exports = {
query: (text, params) => pool.query(text, params),
}

How to establish connection to mongo db in a Node js express server using serverless?

I don't know how to establish connection to the mongo db for my node JS server in AWS Lambda using serverless on AWS. I've mentioned my question in the handler function below.
The code looks something like this:
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import cookieParser from "cookie-parser";
import serverless from "serverless-http";
const PORT = 1234;
dotenv.config();
mongoose.connect(
process.env.MONGO_URL,
() => {
console.log("connected to db");
},
(err) => {
console.log({
error: `Error connecting to db : ${err}`,
});
}
);
const app = express();
app.use(cookieParser());
app.use(express.json());
// this part has various routes
app.use("/api/auth", authRoutes);
app.use((err, req, res, next) => {
const status = err.status || 500;
const message = err.message || "Something went wrong";
return res.status(status).json({
success: false,
status,
message,
});
});
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
export const handler = () => {
// how to connect to mongodb here?
return serverless(app);
};
Here handler is the AWS lambda's handler function. For each http request I'm reading/writing data from/to my DB in some way. After checking the cloudwatch logs, it was clear that the requests sent to the server result in timeout because the connection to mongodb hasn't been established. So how exactly do I use mongoose.connect here?
I tried doing this:
export const handler = () => {
mongoose.connect(
process.env.MONGO_URL,
() => {
console.log("connected to db");
}
);
return serverless(app);
};
But it didn't work possibly because it's asynchronous. So I'm not sure how to make this connection here.
EDIT:
One thing that I realised was that the database server's network access list had only my IP because that's how I set it up initially.
So I changed it to anywhere for now and made the following minor changes:
const connect_to_db = () => {
mongoose
.connect(process.env.MONGO_URL)
.then(() => {
console.log("Connected to DB");
})
.catch((err) => {
throw err;
});
};
app.listen(PORT, () => {
connect_to_db();
console.log(`Server listening on port ${PORT}`);
});
Now I can see "Connected to DB" in the logs but the requests sent still times out after 15 seconds (the timeout limit set currently).
My logs:
What am I doing wrong?
So I did some more digging and asked this around the community. Few things that made me understand what I was doing wrong:
It appeared I wasn't connecting the db and my app response
together. My app was handling the request fine, my db was connecting
fine. But there was nothing tying them together. It's supposed to be simple:
Requests comes in > App waits until db connection has been established > App handles request > App returns response.
Second, calling app.listen was another problem in my code. Calling listen keeps the process open for incoming requests and it ultimately is killed by Lambda on timeout.
In a serverless environment, you don't start a process that listens for requests but, instead, the listening part is done by AWS API Gateway (which I have used to have my Lambda handle http requests) and it knows to send request information to Lambda handler for processing and returning a response. The handler function is designed to be run on each request and return a response.
So I tried adding await mongoose.connect(process.env.MONGO_URL); to all my methods before doing any operation on the database and it started sending responses as expected. This was getting repetitive so I created a simple middleware and this helped me avoid lot of repetitive code.
app.use(async (req, res, next) => {
try {
await mongoose.connect(process.env.MONGO_URL);
console.log("CONNECTED TO DB SUCCESSFULLY");
next();
} catch (err) {
next(err);
}
});
Another important, but small change. I was assigning lambda's handler incorrectly.
Instead of this:
export const handler = () => {
return serverless(app);
};
I did this:
export const handler = serverless(app);
That's it I suppose, these changes fixed my express server on Lambda. If anything I've said is wrong in any way just let me know.

Make post request to Mongodb Atlas using Nodejs

I was familiar with MongodB for CRUD operation. Here, I'm trying to make simple post request on mongodB atlas but I want to know where I have done error for the connection and posting data to MongodB atlas.
Model.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
let quizSchema = new Schema({
title: {
type: String,
},
description: {
type: Number,
},
question: {
type: String,
},
});
const Quiz = mongoose.model("Quiz", quizSchema);
module.exports = Quiz;
index.js
I'm trying to create the database collection name "QuizDatabase" and insert the data to it.
var express = require("express");
var bodyParser = require("body-parser");
const Quiz = require("./views/model/model");
var Request = require("request");
var app = express();
app.use(bodyParser.json());
const MongoClient = require("mongodb").MongoClient;
const uri =
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.connect(uri);
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
app.post("/new/", function (req, res) {
Quiz.collection("QuizDatabase").insertMany(req.body, function (err, doc) {
if (err) {
handleError(res, err.message, "Failed to create new quiz.");
} else {
res.status(201).send(JSON.stringify(body));
}
});
});
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
res.status(code || 500).json({ error: message });
}
You dont have to use mongo client if you are already using mongoose.
In index.js file just import the model
const Quiz = require("./model");
And you are already using mongoose to connect to db when you write mongoose.connect(uri); You don't have to use client.connect() again.
Query to insert -
Quiz.insertMany(req.body);
Your index file should look like this -
const Quiz = require("./views/model/model");
var Request = require("request");
var app = express();
app.use(bodyParser.json());
const uri =
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
mongoose.connect(uri);
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
app.post("/new/", function (req, res) {
Quiz.insertMany(req.body, function (err, doc) {
if (err) {
handleError(res, err.message, "Failed to create new quiz.");
} else {
res.status(201).send(JSON.stringify(body));
}
});
});
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
res.status(code || 500).json({ error: message });
}
There are several reasons.
Connection Issues to the MongoDB database.
To check this insert app.listen() into mongoose connect. This would make sure you can only run development on your preferred PORT only when it has successfully connected to your Database. e.g From your code
mongoose.connect(uri)
.then(() => {
//listen for PORT request
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
}).catch((error) => {
console.log(error);
});
Try purposely using the wrong Username or Password and see if you get this error:
MongoServerError: bad auth : Authentication failed.
at Connection.onMessage (/Users/user/Documents/..<pathway>../connection.js:207:30)
*
*
*
*
ok: 0,
code: 8000,
codeName: 'AtlasError',
[Symbol(errorLabels)]: Set(1) { 'HandshakeError' } }
If you don't get this error then you have a connection problem. To solve this, I added my current IP ADDRESS and 0.0.0.0/0 (includes your current IP address) at the Network Access page. So you click on MY CURRENT IP ADDRESS and confirm upon setting up the network. Go to NETWORK ACCESS, click on add new IP ADDRESS, input 0.0.0.0/0 and confirm. Then try using the wrong username or password in the URI link given to you to see if it gives the above-expected error, then you can now correct the Username and Password, and npm run dev or npm start (However you configured it in your package.json file).
Code issues
First of I would correct your Model.js file from this:
const Quiz = mongoose.model("Quiz", quizSchema);
module.exports = Quiz;
to this:
module.exports = mongoose.model("Quiz", quizSchema);
I can see why yours can work, but it may be an issue as you want to get the schema upon accessing the whole file.
Secondly, I would correct the code for Posting and you can do that in 2 ways using the asynchronous method. Which depends on the method of assigning the req.body.
Way 1:
app.post("/new/", async (req, res) => {
const { title, description, question } = req.body;
//adds doc to db
try {
const quiz = await Quiz.create({ title, description, question });
res.status(200).json(quiz);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
OR
Way2:
app.post("/new/", async (req, res) => {
const quiz = new Quiz(req.body);
//adds doc to db
try {
const savePost = await quiz.save();
response.status(200).send(savePost);
} catch (error) {
response.status(400).send(error);
}
});
NOTE: You don't necessarily have to create a named database and collection in Mongo Atlas before starting the project. The URI given to you covers that if there are no problems with the connection to the DB or the Code.
based on your code
URI:
"mongodb+srv://username:password#cluster0.iom1t.mongodb.net/QuizDatabase?retryWrites=true&w=majority";
would create a database called: QuizDatabase and collection called: quizs (MongoDb always creates the plural word from the model given and makes it start with lowercase (i.e from your Model.js, the mongoose.model("Quiz"))).
If no database is named in your URI, then a database called test is automatically created for you as a default database, with the collection name being the mongoose.model("") given.
CONCLUSION
This should solve at least 90% of your issues, any other creation/POST problems is currently beyond my current expertise. Happy Coding 🚀🚀🚀

Socket.io: Failed GET requests in the console

I am trying to add socket.io to my code, and the following failed GET request is repeatedly printed to the console whenever I run the website on my localhost.
GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MMNC8I9 0 ()
I do not understand what is sending this request. The socket works, although not entirely in the way I intended it to*.
*I am trying to build a real-time application that works with several clients, and at the moment only one client is being updated at any given time. As I am still learning, I am not sure if this is a normal behaviour or not, but I want to fix the failed request error before I dive into that!
How do I fix the issue? Thank you in advance!
Code below:
server.js
const client=require("socket.io").listen(4040).sockets;
const app = express();
mongoose.connect('mongodb://localhost/<dbname>?replicaSet=rs');
mongoose.connect(config.db);
const db = mongoose.connection;
db.once("open", () => {
console.log(">>> 🖥️ MongoDB: Connection successful");
app.listen(9000, () => {
console.log('Node server running on port 9000');
});
// Connect to Socket.io
client.on("connection", function(){
let queries = db.collection('queries');
// Create function to send status
sendStatus = function(s) {
socket.emit("status", s);
}
});
});
app.post('/query', (req, res, next) => {
<some code omitted>
doc.save()
.then(result => {
socket.emit("query", res);
res.send({
result
});
}
});
Queries.js
constructor(props) {
...
var socket = io.connect("http://localhost:4000/");
if (socket!= undefined) {
socket.on("query", function() {
this.loadQueries();
});
}
index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>

Resources