Is Meteor backend code always available on client-side? - javascript

I created test Meteor application and I found that overall code (server-side too) available to look with dev tools on a client.
Test app (In browser):
(function(){ if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to test_app.";
};
Template.helo.events({
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
}).call(this);
Is this by design? Can server-side code stay at server?

If you want to keep server side code on the server you have to restructure your app.
Make these directories in the root directory of your application:
/server - stores everything to run on the server only
/client - stores everything to run on the client only
/public/ - stores anything that should be accessible in at http://yoursite/ (i.e images, fonts). If you place an image a.jpg in /public it will be available at http://yoursite/a.jpg
Once you use this structure you don't have to use the if(Meteor.isServer) {..} or if(Meteor.isClient) {..} conditions anymore as they would run in the right place.
When you put files in the root directory of your meteor application, they would run on both the client and the server so this is why the file is unaltered & everything in the if(Meteor.isServer) would only run on the server.
It is by design and quite helpful to share code between the server and client, though it would be visible to both the client & server

Related

NodeJs: How do I access the functions of my JavaScript backend from my HTML frontend?

Here is my HTML code in index.html.
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="stuff()">Click</button>
<script>
async function stuff() {
await connectToServer();
}
async function connectToServer() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
alert(this.responseText);
};
xhttp.open('GET', 'C:/Users/myName/myFolder/index.js', true);
xhttp.send();
return;
}
</script>
</body>
</html>
Then, here is my backend code in index.js.
const express = require('express');
const axios = require('axios');
const port = process.env.PORT || 8080;
const app = express();
app.get('/', (req, res) => {
res.sendFile('C:/Users/myName/myFolder/views/index.html');
});
app.listen(port, () => console.log(`Listening on port ${port}`));
I can type node index.js on the command line and run this program and go to http://localhost:8080/ . When I do this, the html page shows up as intended. However, when I click the button in order to make a GET request to the server side, I get a console error saying Not allowed to load local resource: file:///C:/Users/myName/myFolder/index.js . I'm using Google Chrome by the way.
I know that it is a security thing, and that you are supposed to make requests to files that are on a web server (they begin with http or https). I suppose then, my question is:
How do I make it so that my server file index.js can be viewed as being on a server so that I can call functions on the backend from my frontend?
You have to make an HTTP request to a URL provided by the server.
The only URL your server provides is http://localhost:8080/ (because you are running an HTTP server on localhost, have configured it to run on port 8080, and have app.get('/', ...) providing the only path.
If you want to support other URLs, then register them in a similar way and write a route to handle them.
The express documentation will probably be useful.
You should not need to load your server-side code into the browser. It's server-side code. It runs on the server. It isn't client-side code. It doesn't run in the browser. The browser does not need access to it.
If you want to load some actual client-side JS from the server, then use <script src="url/to/js"></script> (and not Ajax) and configure express' static middleware.
Let's improve your current flow by separating your backend API process from frontend hosting process. While backend can, it's not good in serving static html files (especially for local development purposes).
Run your backend as usual, node index.js. But as soon as this command will become more complicated, you will probably want to use npm scripts and do just npm start)
Run separate server process for frontend. Check out parcel, snowpack, DevServer. It can be as easy as npx parcel index.html, but this command is likely to change frequently with your understanding of your tool features.
To call backend, just add an API endpoint to an express app (just like you already did for serving static content), and call it, using backend process URL.
Usually, you will see your app on http://localhost/ and it should do requests to http://localhost:8080/.
If for some strange reason you will want to dynamically download js file from your server to execute it, you just need to serve this file from your frontend hosting process. In order to do so, different development servers have different techniques, but usually you just specify file extensions and paths you want to be available.
After editing frontend files, you will see hot-reload in browser. You can achieve the same for node process with various tools (start googling from nodemon)
If you find this way of operating not ideal, try to improve it, and check what people already did in this direction. For example, you can run two processes in parallel with concurrently.

Integrating node modules and JavaScript into our Web API controller calls

Our main backend server is a .net 5 web API project. I'm needing to integrate some javascript modules and javascript code into our functionality. I'm wanting to save on the time of rewriting these modules all into c# to access from our code. Are there any packages or methods to accomplish this or am I best of running a separate node server for this functionality?
Option 1. Access A Node.js Server Script From C#/.Net 5
Jering.Javascript.NodeJS enables you to invoke javascript in a Node.js module from C#. With this ability, you can use Node.js scripts/modules from within your C# projects. Supports: Callbacks, Promises and Async/Await. Get js scripts via file path, string or stream. You can run a single global instance of your Node.js App that remains in memory or create a new instance for each call. See an example on Invoking Javascript From File.
Install Via Package Manager or .Net CLI
Install-Package Jering.Javascript.NodeJS
#or
dotnet add package Jering.Javascript.NodeJS
some-module.js
module.exports = {
doSomething: (callback, message) => callback(null, { message: message + '!' }),
doSomethingElse: (callback, message) => callback(null, { message: message + '.' })
}
In your .Net App
var services = new ServiceCollection();
services.AddNodeJS();
ServiceProvider serviceProvider = services.BuildServiceProvider();
INodeJSService nodeJSService = serviceProvider.GetRequiredService<INodeJSService>();
public class Result {
public string? Message { get; set; }
}
Result? result = await nodeJSService.InvokeFromFileAsync<Result>("some-module.js", "doSomething", args: new[] { "success" });
Assert.Equal("success!", result?.Message);
This is a basic implementation example. You should see the Jering.Javascript.NodeJS Docs for complete examples of installation, configuration and usage.
Option 2. HTTP REST / Web Socket
Create an HTTP Rest or WebSocket Wrapper around your JS scripts and call them from the .Net App. In your .Net App, use HttpClient class to make HTTP requests. Then over in Node.js wrap your scripts with routes to access various methods. Something like:
const express = require('express');
const app = express();
const port = 3000;
app.get('/some/endpoint', (req, res) => {
// Gets executed when the URL http://localhost:3000/some/endpoint
// Do your thing here
// Return it back to .Net with:
res.send(JSON.stringify({some_response: "Hello There"}))
});
// Start the http server
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
});
Using the HTTP Rest/WebSocket option will require that you already have your node.js app running (and keep it running) before you attempt to call the endpoints from .Net.
Option 3. Execute Standard Javascript Embedded Scripts
Here are the most popular .Net modules that will allow you to run Standard Javascript code within your C# .Net Service. However, these both execute your JS Scripts using the V8 Engine and will not work for Node.js specific methods such as FileSystem. These will also not allow the use of require() or Import. This might be a good option if you have very limited Javascript needs and will not be adding additional JS functions in the future.
Microsoft.ClearScript
Jint
Javascript.Net
This option is quick and simple for very small scripts, but would be the most difficult to update and maintain your JS scripts.

How to run function when NodeJS server starts?

Hello I need to run a function on first start of the server, basically I want to put some constant data in the database. Yes, I could use just a in memory constant for this but I'd rather have it in my database because I am planning on using that data on some of my other servers in the future. The problem is, I am using NextJS and I want to host on the Vercel platform so I don't want to use a custom server.js file.
Is there any way to run a function only once when the server first starts in NextJS/NodeJS?
So the Vercel platform is serverless: https://vercel.com/docs/serverless-functions/introduction.
As it states in the documentation you can create a serverless function like so:
module.exports = (req, res) => {
res.send("Hello World");
}
If you wish to run a function after the build is done you can look at this answer:
Next.js run function/script when starting app
You could also use getServerSideProps to run code before the page renders (on the server side) if that is what you mean with "app start".
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

Applying node.js server to a web server

I am trying to learn how to use Node.js and web sockets to create simple multi-user interactive javascript programs. I used this tutorial series by Daniel Shiffman to create this example project. My next step would be to upload it, using WinSCP, to my RaspberryPi apache2 web server, but I haven't found a way to edit the code in a way to allow for that to work, and furthermore, I do not know what piece of the programs to execute to make it function properly.
Any assistance would be great. The extent of my Node / Socket.io knowledge comes entirely from the video series mentioned above, so you can assume I know almost nothing else.
Apache is a web server and it serves your file and send them to client for you, so when you have some client side things like html site with some css, javascript and images you can use apache to send them to client for you.
In node.js you can create this web server simply by following code and express library:
// Create the app
var app = express();
// Set up the server
var server = app.listen(3000, () => {
console.log('http server is ready')
});
as you created in your code too. by this web server you can host your files and do many more things like setup socket.io server and ... because you write web server yourself. with following code you serve static files in public directory (html, css, javascript and images ...):
app.use(express.static('public'));
after you finishing this process you can run it simply by:
npm install
node server.js
if you want you can run you code inside docker by creating Dockerfile and ...
About your question, you must move all your project files into raspberry and at the end you have following directory tree in somewhere in raspberry:
|- server.js
|- package.json
\ public
at this directory run above commands and your server will be up and running and you can access to it by http://raspberry_ip:3000.

MongoDB Cloud9 Connection

So, I am wondering if there is a way to connect to the mongoDB I have setup in my Cloud9 from an html. I mean, I have already connected to the db from the terminal and everything is working like a charm but I need to do some stuff inside my script in an html document and when I try calling the function which contains this code it does nothing
var MongoClient = require('mongodb').MongoClient
, format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/ingesoft', function (err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
});
I have saved the same code into a "file.js" and ran it from console using node file.js and it outputs into the console log "successfully connected to the database", plus the terminal which is running mongo's connection shows me one more connection to the db. The thing is, when I try to run that code inside my script it doesn't work. Sorry for my ignorance I am new to mongo.
Any help would be much appreciated
To simplify your question, here's what's going on:
node file.js containing the code in your question is working
pasting the same code to your html file is not
So, getting to the bottom of the issue, let's ask first: what's the difference between running node file.js and putting the code in html?
The difference is that node ... is running on your Cloud9 workspace (let's call it the server machine).
Your MongoDB server is also running on that server machine
The mongodb npm package you installed is also present on the server machine
The url: mongodb://127.0.0.1:27017/ingesoft references 127.0.0.1 which is the localhost for your server
whereas with the code on your browser:
The code is being run on your customer's machine
That machine doesn't have your Mongodb server
Browser's usually don't support require
You can do requires if you bundle code and use something like webpack or browserify. Did you perhaps do that?
If you did indeed package everything, was the mongodb package that you're requiring packaged?
Can the mongodb package be run from the client side?
The url: mongodb://127.0.0.1:27017/ingesoft references 127.0.0.1 which is the localhost for your customer's machine
Basically, as you can see from the above, the two are very different.
If you want to talk to your db, a lot of people go the following route:
Make a server application that implements some form of REST API
That REST API talks to your DB
Your client code knows how to talk to the REST API and get the required data
That way, you only talk to your MongoDB using your server, and the client can talk to your server via the internet.
This is, of course, an oversimplification, but I hope this resolves your confusion.

Categories

Resources