I'm setting up a express server in electron.How can I stop it in a button handler?
can't find a express API for this.
// create a express server
ipcMain.on('create-http-server', (event, data) => {
const port = data.note;
isPortAvailable( data.note ).then(() => {
const test = httpApp.listen( port );
event.reply('create-http-server-reply',{ result:'success'} );
})
.catch( err => {
event.reply('create-http-server-reply',{ result:'failed',err:err } );
})
})
ipcMain.on('stop-http-server',(event,data) => {
// how to stop express server here?
console.log( data )
})
Related
on my machine i get a json response when i consume my api and eveything is working fine , but the weird thing is my api not giving me data when i upload it online , i am using namecheap shared hosting , this is the result i get when try to consume api
this is my index.js code
app.get("/project/index/login", (req, res) => { (async () => {
try {
await client.login();
res.send("Login successful!");
} catch (err) {
res.send("Login failed!");
} })(); });
app.get("/project/index/user/:id", (req, res) => {
const id = req.params.id; (async () => {
try{
const data = await client.getInfo({ id: id })
res.json(data.data);
}catch(error){
res.send(error);
}
})(); });
app.listen(port, () => {
console.log(`Listening on port http://localhost:${port}...`);
});
It's probably because your API server is running only on localhost. Check your API server!. You must run the API server which has a domain.
I would like to configure my project in order to run unit test for some API endpoints (that call the database). I'm using :
ExpressJS
MongoDB (no Mongoose)
Mocha / Chai
Mongodb Memory Server (to mock the DB)
// app.ts
export const app = express();
const port = process.env.PORT;
app.use("/my-route", myRoutes);
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
// database.ts
export const mongoConnect = async () => {
try {
let MONGODB_URI = process.env.MONGODB_URI;
if (process.env.NODE_ENV === "test") {
const mongoServer = await MongoMemoryServer.create();
MONGODB_URI = mongoServer.getUri();
}
const client: MongoClient = await MongoClient.connect(MONGODB_URI);
_db = client.db("dbName");
_mongoClient = client;
if (process.env.NODE_ENV === "test") {
console.log("Connected to MongoDB Test");
} else {
console.log("Connected to MongoDB");
}
} catch (err) {
console.log("Error connecting to MongoDB:", err);
throw err;
}
};
export const getMongoClient = () => {
if (_mongoClient) {
return _mongoClient;
}
throw "Mongo client doesn't exist";
};
export const getDb = () => {
if (_db) {
return _db;
}
throw "No database found!";
};
// test.ts
let mongoClient: MongoClient;
let db: Db;
before(function (done) {
mongoConnect()
.then(() => {
db = getDb();
mongoClient = getMongoClient();
return db.createCollection("wordsCollection");
})
.then(() => {
db.collection("wordsCollection").insertMany(data);
})
.catch((err) => console.log(err))
.finally(() => done());
});
after(function (done) {
db.dropDatabase();
mongoClient.close().then(() => {
done();
});
});
it("test", async function () {
let res = await chai
.request(app)
.post("/my-route/hello")
.send({ excludeIds: [] });
expect(res.status).to.equal(200);
});
});
But it's not working...
If I call mongoConnect() in test.ts it console.log twice Connected to MongoDB Test. But if I don't call the function it throws me error because MongoClient is undefined.
I think await chai.request(app) already calls the database and server but I need to create Collection and Documents before. So I need to connect to the DB before the test.
Any help would be greatly appreciated.
I found a solution, I don't know if it's best practice but it works and is pretty easy, thanks to this post : https://stackoverflow.com/a/70285190/10547153.
I needed to add a condition in app.ts before making the connection to the database and the server in order to launch them only if it's called by Node itself.
if (require.main === module) {
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
}
When a file is run directly from Node.js, require.main is set to its
module. That means that it is possible to determine whether a file has
been run directly by testing require.main === module.
Now I can connect to the mocked database from test.ts and only one connection will be triggered.
I'm building an web app to receive data from an api using nodejs as backend, and show this data on the client side using React. But it's my first time using socket.io.
Sockets.ts
function socket( io ){
io.on("connection", socket => {
var socketId = socket.id;
var clientIp = socket.request.connection.remoteAddress;
console.log('New connection ' + socketId + ' from ' + clientIp);
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
}
export default socket;
router.controller.ts
export const getData: RequestHandler = async (req, res) => {
const options= {
method: 'GET',
};
const response = await fetch(citybikeurl, options)
.then((res: any) => res.json())
.catch((e: any) => {
console.error({ error: e });
});
console.log("RESPONSE: ", response);
res.json(response);
}
routes.ts
router.get('/', dataController.getData)
At the moment, I don't know if I'm passing any data from controller.ts to Sockets.ts, and after of this be able to emit the results.
You should be using a socket on the server-side as well.
Please refer to this guide for how to set up a socket server:
https://medium.com/#raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891
I have an Express REST API server written in TypeScript.
At first, I started server like this -
const initServer = async() => {
await connectDb();
await server.listen(secrets.port, secrets.hostname, () => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
});
}
initServer().catch(error => logger.error(`Init server went wrong with: ${error}`));
Then I read a blog post suggesting to use .then().catch() -
async function initServer() {
// Connect the database first
await connectDb()
.then(() =>
// then start the server
server.listen(secrets.port, secrets.hostname, () => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
})
)
.catch(err => {
logger.error(`Initializing server went wrong with: ${err}`);
process.exit(1);
});
}
Then I read another blog post saying "catch the error first" -
async function initServer() {
// Connect the database first
await connectDb()
// then start the server
.then(() => server.listen(secrets.port, secrets.hostname))
.catch(err => {
logger.error(`Initializing server went wrong with: ${err}`);
process.exit(1);
})
// then announce the server info
.finally(() => {
logger.info(
`Running server at http://${secrets.hostname}:${secrets.port} in ${
secrets.env
} env and API version is ${secrets.apiVersion}`
);
});
}
But I feel like I'm not doing it right. Please educate me what I'm doing wrong.
How should I start the server?
The problem that I have is that my express server starts before the database connection is established. People can send requests to the application while the connection is not yet there for some time:
const app = express();
dbClient.connect()
.subscribe(() => console.log('connection established!'));
module.exports = app.listen(8080, () => {
console.log('the server is running');
});
The outcome of this is:
the server is running // some seconds break
connection established! // now everything works properly
How can I start listening to events only after the subscriber has been run?
The only way to ensure you are connected before to listen is to chain it. If you experience trouble about exporting the result is because you are mistaking import/export. Import/export should not have any impact on your system. Every actions should be triggered and not implied.
You should consider putting all your Express handling into a class and then use it in your controller. This way you could handle errors ... As example :
// File a.js
let instance = null;
export default class ServerApi {
constructor() {
if (instance) return instance;
instance = this;
return instance;
}
static getInstance() {
return instance || new ServerApi();
}
startServer(callback) {
const app = express();
dbClient.connect()
.subscribe(() => {
console.log('connection established!');
app.listen(8080, () => {
console.log('the server is running');
callback();
});
});
}
stopServer() { ... }
getServerStatus() { ... }
};
// File controller.js
import ServerApi from 'a.js';
ServerApi.getInstance().startServer(() => {
// handle error
// handle success
});
There are few ways to achieve this.
one a ways to wrap app.listen into observable
const app = express();
const connectApp = (port = 8080) => new Observable(observer => app.listen(port, () => {
observer.next(app);
observer.complete();
});
dbClient.connect()
.pipe(
tap(() => console.log('connection established!')),
mergeMap(() => connectApp()),
tap(() => console.log('the server is running')),
)
.subscribe(() => console.log('Enjoy'));