ES6 access exported 'default' instance from same file - javascript

I was wondering, when you export some data using the ES6 keyword export like so :
export default {
data: "Hello !"
}
How can you then from the same file, access that exact same exported data ?
EDIT: Of course, without declaring it before exporting the variable...

If you structure your file like that, you cannot.
Usually, you define functions and data that you want to expose before the export statement, and then reference them when you build the exported object/function.
Bad way:
export default {
data: 'Hello!',
myFn: function (str) {
console.log(str);
}
}
Good way:
var data = 'Hello!';
var myFn = function (str) {
console.log(str);
};
// code that uses data and myFn
// shorthand for { data: data, myFn: myFn }
export default { data, myFn };

Try the following
export const data = 'hello';

For my similar use case -- I wanted easy access to everything the ES6 module exported from within the same module just for debugging purposes. So:
export const data = 'hi'
export const someFunc = () => `important data: ${data}`
export default someFunc()
export const funcToDebug() => {
console.log(`what's going on here? ${myModule.exports.default}`)
}
var myModule = module

If you want to access internally the functions that you export, you should define them outside of the export statement. Like so:
const data = 'Hello !';
const someFunc = () => {
return data + ' Goodbye!'
}
export default {
data,
someFunc
}
Now the variables and functions can reference each other without being "stuck" inside the export function. For example the following will NOT work:
// WRONG!
export default {
data: 'Hello !',
someFunc: () => {
return data + ' Goodbye!';
}
}

Related

JavaScript - How to call a method of a imported JS file

How to define a method 'foo' in a javascript file 'test.js' so that I can import that file into another javascript file and call the method 'foo'?
Before going further you'll need to figure out what kind of modules you're using, there're 2 common types of modules that I know CommonJS and ES
In either type of module you're using, in order for you to import your method, you will need to export it as a module first.
The details of their differences are found in the NodeJS document NodeJS Import
For the ES modules you can export your method 'foo' like this:
// normal function
export function foo1() {}
// arrow function
export const foo2 = () => {}
// or this grouping style that I prefer would look more elegant
function foo1() {}
const foo2 = () => {}
// we can export multiple methods at once
export {
foo1,
foo2
}
On the other hand, using the CommonJS module, you can export your method 'foo' like this:
// a single method
module.exports.foo1 = function() {}
module.exports = function foo2() {}
// multiple methods
module.exports = {
foo1: () => {},
foo2: () => {}
}
Once you've exported your methods as modules, you can now import them like this:
import { foo1, foo2 } from './test.js'
const exec = foo1();
or
import * as test from './test.js'
const exec = test.foo2();
Hope this help

Checking variable status from another JavaScript module using export default

I have two Javascript modules, one for my navigation, and one for route changes.
Inside of nav.js is simple if to check if the menu can be opened
const initNav = () => {
const openMenu = () => {
if (!menuIsOpen && isMobile) {
navItems.classList.add("is-menu-open");
menuIsOpen = true;
} else {
navItems.classList.remove("is-menu-open");
menuIsOpen = false;
}
}
}
initNav();
export default initNav;
Then, at the top of the other module I import
import initNav from './nav.js';
The question is, inside of my other module route.js, I need to be able to check if the menu is opened, and, if it is then close it, so I was going to use:
beforeLeave: function (data) {
if (menuIsOpen) {
navItems.classList.remove("is-menu-open");
menuIsOpen = false;
}
}
The console, however, says menuIsOpen is not defined.
I can't then this way check to see the status of this variable.
Am I able to do this another way, rather than combining the two modules into one very large js module?
The problem is that you're trying to reassign a variable that exists in multiple modules, but imported variables are read-only references - they can only be reassigned in their original module. So you can't just also export the menuIsOpen from nav.js because reassigning it in route.js would not be allowed.
You could have nav.js export a function that reassigns its menuIsOpen while also exporting menuIsOpen, but reassignable exports in general are unintuitive - nowhere else in Javascript does what looks like a reference to a primitive value seemingly reassign itself due to a different module reassigning the binding. Linters often forbid them.
A better alternative is for the main user of menuIsOpen to export setter and getter functions to interface with menuIsOpen. For example, you could do something like the following:
// nav.js
export const getMenuIsOpen = () => menuIsOpen;
export const setMenuIsOpen = (newVal) => menuIsOpen = newVal;
// ...
// route.js
import initNav, { getMenuIsOpen, setMenuIsOpen } from './nav.js';
// ...
beforeLeave: function (data) {
if (getMenuIsOpen()) {
navItems.classList.remove("is-menu-open");
setMenuIsOpen(false);
}
}
For anything more complicated than a single variable that needs to be accessed and changeable in multiple places, you can consider exporting an object instead, eg:
// nav.js
export const navState = {
menuIsOpen: false,
// other properties
};
// ...
// route.js
import initNav, { navState } from './nav.js';
// ...
beforeLeave: function (data) {
if (navState.menuIsOpen) {
navItems.classList.remove("is-menu-open");
navState.menuIsOpen = false;
}
}
Having to handle mutable state across multiple modules makes code a bit ugly. I prefer to avoid it when I can. Given the code in the question, since you already have a reference to navItems in both modules, you might be able to avoid having a persistent menuIsOpen variable at all if you simply check if the navItems class list has is-menu-open:
// nav.js
// ...
const openMenu = () => {
// defining menuIsOpen as a standalone variable isn't necessary,
// but you might find it makes the code more readable
const menuIsOpen = navItems.classList.contains('is-menu-open');
if (!menuIsOpen && isMobile) {
navItems.classList.add("is-menu-open");
} else {
navItems.classList.remove("is-menu-open");
}
}
// ...
// route.js
// ...
beforeLeave: function (data) {
const menuIsOpen = navItems.classList.contains('is-menu-open');
if (menuIsOpen) {
navItems.classList.remove("is-menu-open");
}
}
If you do need a standalone menuIsOpen variable in nav.js, you could have nav.js export a function which can close the menu and set menuIsOpen to false:
// nav.js
// ...
export const closeMenu = () => {
navItems.classList.remove("is-menu-open");
menuIsOpen = false;
};
// ...
// route.js
import initNav, { closeMenu } from './nav.js';
// ...
beforeLeave: closeMenu
(if beforeLeave really isn't doing anything else in your actual code other than checking if the class exists and removing it if so, you don't need to check if the class exists first - you can just remove it from the class list unconditionally - this can apply to all the other snippets in the answer too)
try getter/setter or export the variable menuIsOpen
Try like this
beforeLeave: (data) => {
if (menuIsOpen) {
navItems.classList.remove("is-menu-open");
menuIsOpen = false;
}
}

JS ES6: How to give child methods access to their sibblings?

I have multiple utility methods like
export const makeTextUtils = ({ U }) =>
Object.freeze({
hello: () => "Hello World!",
lorem: () => "Lorem ipsum..."
)};
these child utils can reference each other
export const makeOutputUtils = ({ U }) =>
Object.freeze({
logHello: () => console.log(U.txt.hello())
)};
Now I want to expose the Utils in a utils.js and inject the parent Method into all children
import { makeTextUtils } from './text';
import { makeOutputUtils } from './output';
// dependency injections
const textUtils = makeTextUtils({ U });
const outputUtils = makeTextUtils({ U });
// building parent util method
export const U = Object.freeze({
txt: textUtils,
out: outputUtils
});
I've tried various ways of importing the U at the top of the main file and switching up the order within the file, but nothing seems to do the trick.
Any help would be much appreciated.
First declare the U object at the top so that you can pass it down to the other functions. Then, after U gets properties assigned to it, you can freeze it:
import { makeTextUtils } from "./text";
import { makeOutputUtils } from "./output";
export const U = {};
// dependency injections
const textUtils = makeTextUtils({ U });
const outputUtils = makeOutputUtils({ U });
// building parent util method
Object.assign(U, {
txt: textUtils,
out: outputUtils
});
Object.freeze(U);
U.out.logHello();
https://codesandbox.io/s/happy-benz-cu3n5
The passing of U inside an object and immediately destructuring it in the utility functions doesn't seem to do anything - unless there's a particular reason for that, feel free to just pass the U object alone (and to use the U parameter alone).

Unable to access Vue.js global function through plugin

I'm trying to refactor some commonly used functions into a globally available Util plugin for my app. I followed the instructions from the docs and this question, but I'm not sure how to use it the functions in the template and Vue keeps complaining about an undefined method. Ideally I just want to call isEmpty from any child component.
util.js
export default {
install(Vue, options) {
Vue.isEmpty = function (object) {
return false // dummy function for now to check if method works
}
}
}
Also tried:
Util.install = function (Vue, options) {
Vue.isEmpty = function () {
...
}
// this doesn't work either
// Vue.prototype.$isEmpty = function (object) {
// return false
// }
}
main.js
import util from './components/shared/util.js'
import comp from './components/shared/myComponent.js'
// Vue.component('util', util) this doesn't work
Vue.use(util)
const app = new Vue({
...
components: {
comp
}).$mount('#app')
None of the below work. The error thrown is TypeError: Cannot read property 'isEmpty' of undefined
component template
<p v-if="util.isEmpty(license)" class="margin-0">N/A</p>
<p v-if="Vue.isEmpty(license)" class="margin-0">N/A</p>
<p v-if="isEmpty(license)" class="margin-0">N/A</p>
You are almost done, are missing of prototype. Try this:
utils.js
export default {
install(Vue, options) {
Vue.prototype.isEmpty = function (object) {
return false // dummy function for now to check if method works
}
}
}
Component
<p v-if="isEmpty(license)" class="margin-0">N/A</p>
Here a example: https://codesandbox.io/s/vue-template-tdx00

Getting error when import instanceMethods function in Sequelize

I have created inside a file a function and export it using
export function foo(params...) {
// do something
}
inside the initialization of the model I import the function in this way:
import { foo } from "../path/..."
instanceMethods: {
foo: foo
}
the problem is the model is not initialized correctly. Do you know why?
the problem is the model is not initialized correctly
The following code works fine.
export function foo(params...) {
// do something
}
import { foo } from "./foo";
let instanceMethods = {
foo: foo
};
Error is elsewhere. Perhaps you meant to use = and used :? Note that if you don't use the variable it is erased form the output (ref).
#)-'--

Categories

Resources