How to Create a function in Node.js - node.js

I am using Firebase function to create an API and at the same time I Am using the Firebase Firestore as my database.
I am using Node.js to create the program.
I wanted to know how to create a function in Node.js.
I will be calling a code more than once and since I have been use to Java and Java has molecularity will it be possible in Node.js also?
This is my code
exports.new_user = functions.https.onRequest((req, res) => {
var abc=``;
if(a=='true')
{
abc=Function_A();//Get the results of Function A
}
else
{
abc=Function_B();//Get the results of Function B
//Then Call Function A
}
});
As shown in the code I would be calling the same function two times from different location depending upon the situation and then utilizing the result of it.
Is it possible to declare a function and then call if from different locations and then utilize its result?
Any help would be really appreciated as I am new to Node.js

If you are trying to just get a value back from the function it depends if you are doing synchronous (adding 2 numbers together) or asynchronous (doing an HTTP call)
synchronous:
let abc = 0;
if(a=='true')
{
abc = Function_A();//Get the results of Function A
}
else
{
abc = Function_B();//Get the results of Function B
//Then Call Function A
}
function Function_B() {
return 2+2;
}
function Function_A() {
return 1+1;
}
asynchronous:
let abc = 0;
if(a=='true')
{
Function_A(function(result) {
abc = result;
});//Get the results of Function A
}
else
{
Function_A(function(result) {
abc = result;
});//Get the results of Function A
}
function Function_B(callback) {
callback(2+2);
}
function Function_A(callback) {
callback(1+1);
}
Asynchronous with variable:
let abc = 0;
Function_A(2, function(result) {
abc = result; //should by 4
});//Get the results of Function A
function Function_A(myVar, callback) {
callback(myVar * 2);
}

Related

How to run a function in caller context?

I have a function in a module that simulates shell.
function shell() {
while(1) {
let code = readline.question(">> ");
if(code == "") continue;
if(code == "exit") break;
try {
console.log(eval(code));
} catch (e) {
console.log(e.message);
}
}
}
module.exports = shell;
I'm calling this shell function inside another js file in hope of accessing all the variables and functions defined inside that caller function. Like below:
const shell = require('./shell.js');
var EXPIRY_DATES = ["28MAY2020"];
shell();
function parse_data() {
return "somedata";
}
But I'm not able to access EXPIRY_DATES and parse_data() from inside the shell. How to do this?
(I tried call and bind but not successful.)
Consider passing an object containing the properties (variables) you want the other script to be able to access, then reference that object when evaling:
function shell(vars) {
const result = eval('vars.EXPIRY_DATES');
console.log(result);
// other code in shell
}
(() => {
var EXPIRY_DATES = ["28MAY2020"];
shell({ EXPIRY_DATES });
module.exports = shell;
})();
Logged result:
[ '28MAY2020' ]

How do I return value from inner function without creating chain of return?

function xyz() {
function abc() {
function haha() {
return 5;
}
return haha();
}
return abc();
}
console.log(xyz());
I get '5' in console. Thats ok. Its a simple code of larger problem where there is lots of nested functions. I dont want to return one after the other. Is there any way, I can return from any function and return it to original function caller.
function xyz() {
function abc() {
return 5;
}
return abc()
}
console.log(xyz());
ok maybe you need call backs. I don't get the context of what you are trying to do but I'll just try.
function logTheAnswer (a) {
console.log(a)
}
function add(a, b, cb) {
cb(a + b)
}
add(1,2,logTheAnswer)
now you can nest the call backs indefinitely though try to keep it a minimum as you will experience call back hell.
Sorry to say but your question is a bit confusing without a proper output representation. But you can use callback functions with which you can easily manage your nested calls and returns.
function myFunc3(a, b, callback3){
callback3(a+b);
}
function myFunc2(a, b, c, callback2){
myFunc3(a+c, b, function(result2){
callback2(result2);
})
}
function myFunc1(){
myFunc2(a,b,c, function(result1){
console.log(result1);
})
}
Add a return the from abc function call
function xyz() {
function abc() {
return 5;
}
return abc();
}
console.log(xyz());
Or return an IIFE (Immediately Invoked Function Expression)
function xyz() {
return (function abc() {
return 5;
})();
}
console.log(xyz())

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

Need to execute function when forEach functions ends

I have this code in node js / firebase :
ref.child("recipts").once("value", function(usersSnap) {
usersSnap.forEach(function(reciptsSnap) {
reciptsSnap.forEach(function(reciptSnap) {
reciptSnap.ref.child("last_recipt").once("value", function(b) {
b.forEach(function(c) { //Here I fill some "product" object
});
});
reciptSnap.forEach(function(b) { //Here I fill some "product" object
});
});
});
});
I need to execute a function just when "reciptSnap" forEachs finished. How can I accomplish this, I try using a variable i++ and i-- but only work for one forEach iteration.
The function I call is for manipulating the product object I created with the filled data from the forEachs loops.
If I have understood correctly, you want to call a function when reciptsSnap.forEach is complete and all async tasks inside it are also complete.
For achieving this, you can use the index parameter and the original array that is passed to the callback function of forEach. (See Documentation)
The code will be like this:
(Note: The following code is without changing the current forEach loop structure used. However, re-writing the code with Promise or async would be a better & cleaner way to do it).
var loop1Done = false;
var loop2Done = false;
ref.child("recipts").once("value", function (usersSnap) {
usersSnap.forEach(function (reciptsSnap) {
reciptsSnap.forEach(function (reciptSnap, index, colA) {
const idx = index;
const col = colA;
reciptSnap.ref.child("last_recipt").once("value", function (b) {
const i = idx;
const c = col;
b.forEach(function (c, j, colB) { //Here I fill some "product" object
// Do what you want here
// Check if all done for this loop
if ((j >= colB.length) && (i >= c.length)) {
loop1Done = true;
// Check if all loops done
if (loop1Done && loop2Done) {
// Call final callback function
// e.g. myFinalCallback();
}
}
});
});
reciptSnap.forEach(function (b, k, colC) { //Here I fill some "product" object
const i = idx;
const c = col;
// Do what you want here
// Check if all done for this loop
if ((k >= colC.length) && (i >= c.length)) {
loop2Done = true;
// Check if all loops done
if (loop1Done && loop2Done) {
// Call final callback function
// e.g. myFinalCallback();
}
}
});
});
});
});
Try:
reciptSnap.child("last_recipt").forEach(function(b) {
b.forEach(function(c) {
//Here I fill some "product" object
});
});
This should work since all of your data should already have been fetched when you did "value" on the receipts node.
If this works, your code is no longer asynchronous and right after the last forEach, you can execute the function you wanted to.
reciptSnap.forEach(function(b) {
//Here I fill some "product" object
});
//Execute your function here
});

Javascript accessing object and array defined in modular function

This is a bit foreign to me and I'm probably not understanding it correctly. This is what I have:
var imgModule = (function() {
var imgLocations = {};
var images = [];
imgLocations.setImage = function(img, location) {
imgLocations[img] = location;
}
imgLocations.getImg = function(img) {
return imgLocations[img];
}
imgLocations.setImageArray = function(img) {
images.push(img);
}
imgLocations.getImageArray = function() {
return images;
}
return imgLocations;
}());
I want to be able to access the imgLocations Object and images array from outside this function. The setting functions work, but
document.getElementById("but").onclick = function() {
console.log(imgModule.imgLocations.getImageArray());
console.log(imgModule.imgLocations.getImg(imgName));
}
Both return "undefined". How do I access these variables? And how can I improve this function? Please be patient with me and explain what I'm doing wrong :) I'm trying to learn it the right way instead of defining a global variable outside all functions.
The reason why this isn't working, is because your imgModule is returning the imgLocations object. That being the case, imgModule will actually be the imgLocations object. So you would access your methods like so:
imgModule.setImage()
imgModule.getImg()
imgModule.getImageArray()
imgModule.setImageArray()
And as #gillesc stated. If you are wanting to keep the current syntax of imgModule.imgLocations.getImg() then you could return the imgLocations like so
return {
imgLocations: imgLocations
}
doing so would allow you to add more functionality to your module
return {
imgLocations: imgLocations,
otherObject: otherObject
}
...
imgModule.otherObject.someFunctionCall();
The problem is you are returning the object created and are not setting it as a property of an object.
So in your case this is how it would work.
document.getElementById("but").onclick = function() {
console.log(imgModule.getImageArray());
console.log(imgModule.getImg(imgName));
}
What you need to do is return it like this
return {
imgLocations: imgLocations
}
If you want the API you are attending to create and still have access to the array which you can not do currently.
You don't access imgModule.imgLocations, since what you return is imgLocations, you should access them as:
document.getElementById("but").onclick = function() {
console.log(imgModule.getImageArray());
console.log(imgModule.getImg(imgName));
}
It seems you try to write module pattern.
For deep understanding, I recommend you following article:
The Module Pattern, by Addy Osmani
and pay attention to example with counter:
var testModule = (function () {
var counter = 0;
return {
incrementCounter: function () {
return counter++;
},
resetCounter: function () {
console.log( "counter value prior to reset: " + counter );
counter = 0;
}
};
})();
// Usage:
// Increment our counter
testModule.incrementCounter();
// Check the counter value and reset
// Outputs: counter value prior to reset: 1
testModule.resetCounter();

Resources