Node JS is says method isn't there when it clearly is - javascript

Alright, so I've created a test project to show off this error. The error being that Node JS can't find my getStr function in my Another object.
This is the code:
test.js
var Another = require('./another.js');
var Other = require('./other.js');
var otherStr = Other.getStr();
console.log(otherStr);
other.js
var Another = require('./another.js');
var str = Another.getStr();
another.js
var Other = require('./other.js');
var str = "other String";
exports.getStr = function(){
return str;
}
And this is my output:
C:\Users\Admin\Desktop\JS DEV\NODE DEV\server\test>node test.js
C:\Users\Admin\Desktop\JS DEV\NODE DEV\server\test\other.js:3
var str = Another.getStr();
^
TypeError: Object #<Object> has no method 'getStr'
at Object.<anonymous> (C:\Users\Admin\Desktop\JS DEV\NODE DEV\server\test\ot
her.js:3:19)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (C:\Users\Admin\Desktop\JS DEV\NODE DEV\server\test\an
other.js:1:75)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
C:\Users\Admin\Desktop\JS DEV\NODE DEV\server\test>
So how do I get Node JS to see Another's getStr function in Other?

What you're dealing with here is a circular dependency. Node.js will let you load modules in a circular way but you need to design your code to account for it. Generally speaking, a circular dependency is a sign that the design is suffering from some flaw. In the code you've shown in the question, another requires other but does nothing with it. So the simplest fix would be to change another so that it does not require other.
If you have to keep the circular dependency for some reason or you want to experiment with circular dependencies for learning purposes, then this would be another possible fix:
var str = "other String";
exports.getStr = function(){
return str;
}
var Other = require('./other');
// Actually do something with Other down here.
By the time other is required another will at least have getStr available. So this takes care of the immediate issue. Note however that your other module does not export anything so your test.js file will still fail at var otherStr = Other.getStr(); Probably you forgot to add this:
exports.getStr = function(){
return str;
}
(Note: I've modified the require call so that it requires other without the .js suffix. Generally, you don't want to put suffixes in your require calls. You want to put a module name which Node can resolve to a file, a package, or something else.)

Related

Static variable in nodejs

I am using ES6 style code within NodeJS.
When trying to create a static variable I get an error.
Code:
'use strict';
module.exports = class Count {
static addToCounter() {
//this.count = this.count + 1 || 1;
this.count = this.count + 1;
console.log(`count: `+this.count);
}
static count = "";
}
Error:
static count = "";
^
SyntaxError: Unexpected token =
at new Script (vm.js:74:7)
at createScript (vm.js:246:10)
at Object.runInThisContext (vm.js:298:10)
at Module._compile (internal/modules/cjs/loader.js:646:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)
at Module.require (internal/modules/cjs/loader.js:626:17)
at require (internal/modules/cjs/helpers.js:20:18)
What is my mistake?
This proposal is still in stage-2. As of now, without the babel plugin transform-class-properties, it is not possible to use the assignment operator along with the static keyword.
If you are not transpiling, you will need to be using at least Node.js v12.4.0 for static class fields. https://node.green/#ESNEXT-candidate--stage-3--static-class-fields-public-static-class-fields shows supported features across Node.js versions.
Also, inside your addToCounter function, you would also need to use Count.count = Count.count + 1. If you want to be able to store properties on each instance, then you would need to remove the static keywords before both the method and the property declaration.

IISNode caching old file names and I can't seem to update it

Hello and thank you in advance.
This may be a rather simple scenario, however, I am new to Nodejs.
I have a main script which I am calling from javascript using IISNode. Everything has worked great until I decided to rename a dependency file.
Files involved:
embed.js <- main script
dev2.js <- required custom script by embed.js
which reads this json file
fred.json renamed to chartio.json
embed.js code relevant to issue:
var http = require('http');
var jwt = require('jwt-simple');
var dashinfo = require('./dev2');
var ORGANIZATION_SECRET = dashinfo.getkey();
var ORG_ID = dashinfo.getorgid();
dev2.js code relevant to issue:
var mariadb = require('mariadb');
var connectioninfo = require('./chartio.json');
module.exports = {
getkey: function () {
return connectioninfo.connection.apikey;
},
getorgid: function () {
return connectioninfo.connection.orgid;
},
and finally, I have my charti0.json file which I cannot post due to sensitive data.
I assure you that everything was working until I renamed fred.json to chartio.json.
I have looked online to see if there is a way to clear the cache but I couldn't find anything that seemed to work, though I am a novice. I also looked at logs. I tried running this in IE and Chrome
This is what I see logged from the error:
Application has thrown an uncaught exception and is terminated:
Error: Cannot find module './fred.json'
Require stack:
- C:\xxx\xxx\GPS411\node\dev2.js
- C:\xxx\xxx\GPS411\node\embed.js
- C:\Program Files (x86)\iisnode\interceptor.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:794:15)
at Function.Module._load (internal/modules/cjs/loader.js:687:27)
at Module.require (internal/modules/cjs/loader.js:849:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (C:\Omnitracs\sylectus-trunk\GPS411\node\dev2.js:3:22)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Module.require (internal/modules/cjs/loader.js:849:19)
Folks, I was able to get this working by doing an old fashion workstation reboot. I changed the filename again to test if the issue returns and it seems to recognize the file changes now. I guess I was just stuck in cache-land, but now I'm free. Thanks for your consideration.

remote function returns undefined or null in electron renderer process

I'm currently very interested in the comprehensive opportunites granted by electron.js and its modules. Unfortunately, I keep getting the same error in my renderer process (named 'connector.js') when trying to start my application.
Here is the error:
App threw an error during load
TypeError: Cannot match against 'undefined' or 'null'.
at Object.<anonymous> (D:\Eigene Dateien\Desktop\Coding\DesktopApps\EVT\extFunctions\connector\connector.js:2:44)
at Object.<anonymous> (D:\Eigene Dateien\Desktop\Coding\DesktopApps\EVT\extFunctions\connector\connector.js:22:3)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (D:\Eigene Dateien\Desktop\Coding\DesktopApps\EVT\main.js:9:1)
And here is my connector.js:
const $ = require('jquery');
const {BrowserWindow} = require('electron').remote;
let Remotewin = remote.getFocusedWindow();
$("#minimize").click(function(){
Remotewin.minimize();
});
$("#maximize").click(function(){
if(!Remotewin.isMaximized()){
Remotewin.maximize();
}else{
Remotewin.unmaximize();
}
});
$("#close").click(function(){
Remotewin.close();
});
As you can see clearly, I wanted to create my own menubar at the top frame of the window, but the functionality is getting seemingly demolished by this error. I already searched half of the internet and stackoverflow, but the every answer I found refered to a webpack and/or electron bug they couldn't directly influence.
That's why I want to clearly point out, that I am NOT using webpack in this project. Only external module I added is jquery, as you can see in the code.
So my question; Have you experiended this error in this context and do you maybe even know a solution? Or can you refer to someone with similiar problems?
Thank you in advance, J0nny
Since getFocusedWindow() is a a static method of BrowserWindow,
let Remotewin = remote.getFocusedWindow();
should be:
let Remotewin = BrowserWindow.getFocusedWindow();

Not able to access another module's function in NodeJS

To break it down and simplify it a bit: Imagine I have three files in my project. One main.js, and two modules: moduleA.js and moduleB.js.
main.js accesses moduleA.js which calls a function from moduleB.js. Now moduleB.js finds out that it needs an information that is only available in moduleA.js. Of course moduleB.js tries to access a function in moduleA.js which is technically able to give this information to moduleB.js but there is an error.
Here is the simplified code.
main.js
var a = require("./moduleA.js");
console.log(a.respond());
moduleA.js
var b = require("./moduleB.js");
module.exports = {
respond: function(){
return b.returnAnswerForModuleA();
},
getSomeInformationOnlyAvailableInA: function(){
return "This is the information we need!";
}
};
moduleB.js
var a = require("./moduleA.js");
module.exports = {
returnAnswerForModuleA: function(){
return a.getSomeInformationOnlyAvailableInA()
}
};
Here is the error message:
/Users/Tim/Code/ChatBot/test/moduleB.js:5
return a.getSomeInformationOnlyAvailableInA()
^
TypeError: a.getSomeInformationOnlyAvailableInA is not a function
at Object.module.exports.returnAnswerForModuleA (/Users/Tim/Code/ChatBot/test/moduleB.js:5:16)
at Object.module.exports.respond (/Users/Tim/Code/ChatBot/test/moduleA.js:5:18)
at Object.<anonymous> (/Users/Tim/Code/ChatBot/test/main.js:3:15)
at Module._compile (module.js:425:26)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:457:10)
at startup (node.js:136:18)
at node.js:972:3
Why cannot I access moduleA.js from moduleB.js?
To restructure my code is not really an option!
Thanks for help!
This looks like an issue with circular dependencies in node.js where a circular dependency causes one module to be resolved as an empty object (thus causing the error you see). See these articles which explain:
Node.js and circular dependencies
Circular dependencies in Node.js
The first article offers two possible solutions: "delaying invocation of dependency until runtime" and "replace circular dependency with dependency injection".
I think you can work around the circular issue by changing module B to this:
var moduleA;
module.exports = {
returnAnswerForModuleA: function(){
if (!moduleA) {
moduleA = require("./moduleA.js");
}
return moduleA.getSomeInformationOnlyAvailableInA()
}
};
This delays the loading of module A in module B until runtime by which time, it is already successfully loaded and in the module cache, thus avoiding the circular dependency.

Cannot access child_process API

I have the following tiny program.js which tries to execute a binary file:
var childProcess = require('child_process');
var path2Binary = '/home/myuser/myproj/bins/mybin';
var par = '--file=' + '/home/myuser/myproj/files/myfile.txt';
var ret = childProcess.execFileSync(path2Binary, [par]);
if (!ret) throw 'Error invoking process!';
var cnt = ret.stdout;
if (!cnt) throw 'Error retrieving output!';
console.log(cnt);
The program tries to execute a binary file and passes it a parameter (a file). The output of this process will be then displayed.
I try to run this: node program.js, but get the following
var ret = childProcess.execFileSync(path2Binary, [par]);
^
TypeError: Object #<Object> has no method 'execFileSync'
at Object.<anonymous> (/home/myuser/myproj/program.js:6:24)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:929:3
More information
I am running on CentOS, Node version is v0.10.36.
I tried running sudo yum install nodejs, but it tells me it is already installed so Node installation looks kinda good.
What's the problem?
On a side note...
If I replace childProcess.execFileSync with childProcess.spawn I get the same.
If I change the first line into the following:
var exec = require('child_process').execFileSync;
Then I get an undefined exception on exec.
Synchronous child processes aren't supported in node v0.10.36 - https://nodejs.org/docs/v0.10.36/api/child_process.html
Looks like it may have been introduced in 0.12.

Categories