Namespace Collision when file name and variable name match? - javascript

I'm running into a bug that only happens intermittently.
Let's say I'm importing a function from a file boats.js
// boats.js
export function inspectBoat(boats) {
console.log(boats);
return true;
}
// ocean.js
import { inspectBoat } from './boats'
export default function ocean() {
const boats = 'many boats';
return inspectBoat(boats);
}
The Babel transpiled version of the last line reads
return (0, _boats2.inspectBoat)(_boats);
On occasion, I'll hit a bug that reads (0, _boats2.inspectBoat) is not a function. The bug goes away when I refresh the page and it'll work perfectly fine.
Is the fact that I have both a boats file and boats variable contributing to this intermittent bug? Or is it an issue with the import statement?
I could try changing my const boats variable name, but due to the intermittent nature of this bug, I wouldn't know if it truly solves the issue. Hoping someone could share some relevant background knowledge on this.

The issue is with the function call in the ocean function. The imported function is named inspectBoat, but the function call is using inspectBoats, which is not defined. Changing the function call to use the correct function name should fix the issue:
// boats.js
export function inspectBoats(boats) {
console.log(boats);
return true;
}
// ocean.js
import { inspectBoats } from './boats'; // exported as "inspectBoats"
export default function ocean() {
const boats = 'many boats';
return inspectBoats(boats);
}

Related

Run imported function via another function

Starting point: With this code I trigger func2 via func1. This works fine so far.
window.addEventListener("click", function (event) {
func1("func2()")
})
function func1(functionAsString) {
eval(functionAsString)
}
function func2() {
alert("success!")
}
The problem:
As soon as I import func2 from another javascript file. I can't run func2 with this code anymore....
I have tried it with both import variants
import * as myfunc from "./xy" // myfunc[functionAsString]
as well as
import {func2} from "./xy" // eval(functionAsString)
and unfortunately I do not get func2 addressed.
Can someone give me the decisive tip? Gladly without .eval()
I recreated your problem in a local environment and it works fine
I also did that on codesanbox and it didn't work here
The problem is that in the codesandbox environment parcel was used which transpiles the files and changes the names of the functions hence it couldn't find the name
Anyway, this should work fine in either case:
import * as myfunc from "./xy"
myfunc['func2']()

Function not working when I import something from another .js file

I have a two .js files, one is the main one and the other is used to write and export the functions.
My problem is: when I import a function from funciones.js to index.js my main function stops working.
This is the code:
Index.js:
import { currentWeather } from './funciones.js';
function findWeather() { //this function stops working
//Defining the APIs for both current weather and forecast
let location1 = document.getElementById('Search').value;
console.log(location1);
//...
Funciones.js:
export function currentWeather(wName) { //the function I am exporting
switch (wName) { //Switch conditions to display the correct status and imges
case "Thunderstorm":
//...
I've got to the conclusion that I'm doing something wrong at exporting, because the main function (findWeather) only stops working by the time I import something. I've tried to write everything in the same file and it works, but the idea is to have separated files.
I've tried to export the function at the end of the file as well, and it still doesn't work.
I've figured it out.
The solution I found is: export the main function (findWeather()) and then call it, or in another .js file, or in a <script> tag in the HTML.
So it would look like:
funciones.js:
export function currentWeather(wName) { //the function I am exporting
switch (wName) { //Switch conditions to display the correct status and imges
case "Thunderstorm":
//...
index.js:
import { currentWeather } from './funciones.js';
export function findWeather() {
//Defining the APIs for both current weather and forecast
let location1 = document.getElementById('Search').value;
console.log(location1);
//...
Index.html:
<script type="module">
import { findWeather } from './index.js';
findWeather();
</script>
Be careful in choosing the name of the functions. Both must have the same name. For example functions.js.If you can, write the complete code to check it.
All files that are involved must have .mjs extension.

webpack doesnt add prototype function to Object from other file

I have a file containing the definition of a Object and in that same file I have a function that is part of this object like so:
export function ARScene(_callbacks) {
this.callbacksObject = _callbacks;
// more fancy code..
}
ARScene.prototype.changeCar = function() {
//some fancy code here
this.loadHDCar(); // THIS LIKE GENERATES A ERROR.
}
now I have a different file containing an other method that is part of the Object called ARScene like so:
import { ARScene } from './arScene';
ARScene.prototype.loadHDCar = function() {
//some more fancy code..
}
What is happening when I build this with webpack and run it in the browser I get the error that this.loadHDCar(); is undefined I guess this happens because webpack doesnt add a file if it is not imported. But how do I make sure that ARScene.prototype.loadHDCar is added to the object in the final output?
I am a complete newbie to webpack and modules. I have found answers on stackoverflow about this but they had slightly different scenarios then me. So their solutions didnt work (or maybe I didnt understand it).
If more context or information is needed please let me know.
How do I make sure that ARScene.prototype.loadHDCar is added to the object in the final output?
You should import it in the arScene module, and you should even create the prototype method in there (where you are defining the class) for visibility.
export function loadHDCar() {
… //some more fancy code
}
import { loadHDCar } from './loadHDCar';
export function ARScene(_callbacks) {
…
}
ARScene.prototype.loadHDCar = loadHDCar;
ARScene.prototype.changeCar = function() {
… // some fancy code here
this.loadHDCar();
};

require exported typescript class in javascript

I'm moving my nodejs project from Javascript to Typescript. It's going to be a slow process, slowly changing things over a few months as i need to tweak stuff.
I've created a typescript class that looks something like this:
// RedisRepository.ts
export class RedisRepository {
public async getDevice(serial: string) : Promise<Device> {
// blah
return device;
}
}
Then in another Javascript file where i need to reference and then call the functions on the above class.
// ExpressApi.js
const repository = require('../Redis/RedisRepository');
async function getRedis(req, res) {
try {
const device = await repository.getDevice('serialnumberxxx');
res.status(200).end(JSON.stringify(device ));
} catch (e) {
logger.error(e);
res.status(500).end();
}
}
however, when it tried to call the function on the repository it says it doesn't exist. Using chrome debugger, i can see that it exists at: repository.RedisRepository.prototype.getDevice. This doesn't seem the correct way to use the function though.
While I appreciate I could just convert ExpressApi.js to Typescript. I'm going to have this problem with many different files. So i need to use it as JavaScript for now. I'll slowly continue to go round the project and change things to Typescript.
As #crashmstr mentioned, you should create a new instance of RedisRepository, then call getDevice method.
If you still want to use
const repository = require('../Redis/RedisRepository');
syntax, you could export default new RedisRepository() from your RedisRepository.ts file.

Set global variable to be accessed from other files - javascript

I found the solution by using global.consoleLog = v => this.log(v));. Now the variable consoleLog is available anywhere.
ORIGINAL QUESTION
Currently I am participating in the battlecode challenge. My question is about Javascript though and accessing a global variable.
I have a minimal working example with two files.
// === robot.js ===
import { BCAbstractRobot } from 'battlecode';
import Test from './test.js';
class MyRobot extends BCAbstractRobot {
constructor() {
super();
this.log("asdf"); // the log function does work
// Test.setConsoleLog(this.log); // way 1
// console.log = this.log; // way 2
}
turn() {
Test.testFunction("hello");
return this.move(0, 1);
}
}
// === test.js ===
let consoleLog = undefined;
function setConsoleLog(c) {
consoleLog = c;
}
function testFunction(s) {
// consoleLog(s); // way 1
// console.log(s); // way 2
}
export default { testFunction, consoleLog, setConsoleLog };
Since battlecode gives you the log function, you cannot use console.log for security reasons. However I want to be able to log from any file. The log function is a property of the MyRobot class, but I want to be able to access the function from other files and functions without passing parameters every time.
I tried a couple ways. First I tried creating an export from a util file (test.js) which would start out as undefined and then be set by setConsoleLog. However, when I attempt to use consoleLog, it is still undefined.
I also tried overwriting the console.log reference, but this only works within one file and the reference is still to console.log in other files.
What would be the recommended way to go about creating a global reference or import to this.log such that any file could import it and access it?
The bot is run within a node vm, but with a bundler as far as I know.

Categories

Resources