ES6 member import not working, but default import works - ecmascript-6

The following code works as expected:
// ./mwe/index.js
let foo = () => 'foo';
const Bar = {
foo
};
export default Bar;
// ./index.js
import Bar from './mwe';
console.log(Bar); // logs an object with a member foo that is a function
However, this doesn't work:
// ./index.js
import {foo} from './mwe';
console.log(foo); // logs undefined
Why doesn't the second variant resolve the member foo correctly?
I interpret the following statement of the documentation
Import a single member of a module. This inserts myMember into the current scope.
import {myMember} from 'my-module';
as meaning that if the module exports an object like Bar, then I can import individual members of Bar using that syntax. My understanding is clearly incorrect, as this doesn't work, but why? What part have I misunderstood?

ES2015 import statements do not destructure objects. They look very much like object destructuring but they are different.
Named imports "destructure" one level deep some exports object that represents the whole module itself. So import {foo} from 'bar' means const { foo } = require('bar') not const { foo } = require('bar').default. Supported statements.
But yet again it is special syntax not object destructuring.
For example you can not do
import { foo: bar } from 'baz' // syntax error
or nested destructuring
import { foo: { bar } } from 'baz' // syntax error
So you need to either export foo as separate named export or use another statement for destructuring
import Bar from './mwe'
const { foo} = Bar

You did not export foo, changing it to export let foo = () => 'foo'; should work.

You used export default, which means only the Bar is exported.
The export default exports only the variable that comes after him.

Related

Importing constants are undefined react redux

I have something like this:
//ActionTypes.js
export const a = 'a';
//Reducer.js
import a from './ActionTypes';
//export reducer function that uses string a
//Actions.js
import a from './ActionTypes';
return {type: a, data: 'something'}
but in both reducer.js and actions.js 'a' is undefined. There is no circular dependancy as far as i know. Pls help
I would export a with curly braces like so:
import { a } from './ActionTypes'
a is a named export because you gave it a variable name when you declared it like this:
export const a = 'a';
The syntax for importing named exports necessitate the use of {}.
The syntax that you've used apply to default exports. See below for an example:
export default function a() {
return 'a';
};
Default exports would not work for constants because you would want to declare a name for the variables. You may not use var, let or const with export default.
For more info, please see MDN docs for export
One other thing, it is convention to use ALLCAPS when naming constants.

How to define function in TypeScript with a destrcutured array as parameter

I'm new to TS, but am very experienced in the latest on JavaScript. I'd like to use features that I'm familiar with in ES6. One in particular is using array destructuring in a function's parameters. I've learned that you can use an interface in TS to do object destructuring like so:
interface FooParameters {
bar: any
}
function foo ({ bar }: FooParameters) {
console.log(bar)
}
foo({ bar: 'fizz' })
// logs "fizz"
But I can't seem to find documentation on converting the following JS to TS
function foo ([bar]) {
console.log(bar)
}
foo(['fizz'])
// logs "fizz"
function foo(...barArray: FooParameters[]) {}
After playing around with advice from #bnieland I was able to surmise the right answer. I needed to define an inline tuple with the corresponding parameters and their types.
function foo ([bar]: [string]) {
console.log(bar)
}
foo(['fizz']) // logs "fizz"

Can I export an object using `export` as "`module.export`"

I think what I am asking for is not possible OOB, but I want to confirm.
We are in a process of upgrading to ES6 (using Babel). Project is a web-site, using AMD (requirejs). I would like to turn a utility module (foolib) into ES6, but consume it from either ES6 (using import) or existing ES5/AMD module.
// foolib.es6
export { // as expected, this doesn't work
method1: function () { ... },
value1: 123.456
};
// consumer1.es6
import foolib from "foolib";
// consumer2.js
define(["foolib"], function (foolib) {});
I understand that the solution is to change foolib.es6 as follows:
export function method1() { ... };
export let value1 = 123.456;
However in reality number of entries returned from foolib is ridiculous. So I was hoping there is a way to export existing object literal without rewriting every line.
Furthermore, I realize that this is most likely impossible, due to the differences between AMD import (using define) and import mechanism (later works with exports object that has values hanging off of it, including default value, while former expects a single value to be returned).
One possible solution that I think might work is to export my object as default from foolib.es6, and then tweak requirejs default loader to inspect imported value for being an esModule and return default value: value && value.__esModule && value.default || value. Should this work? (I'm still hoping there is an easier solution).
The syntax you are using to export the object is invalid because you are not giving the object a name, so it cannot be a named export, and you are not specifying that it is the default export, so it cannot be the default export. Change it to be the default export:
// foolib.es6
export default {
method1: function () {},
value1: 123.456
}
// consumer.es6
import foolib from "foolib";
console.log(foolib.value) //=> 123.456
You can use the babel-plugin-add-module-exports Babel plugin to reinstate a default export as the value of module.exports in Node-land.
And as you discovered, make sure you include this plugin before any other -modules- plugins, for example transform-es2015-modules-amd.
This might be late but alternatively you can use the named export as well which is a little different from the default approach that #sdgluck mentioned.
const method1 = function () {};
const value1 = 123.456;
export { method1, value1 };
I like this approach because you can import them directly like
import { method1, value1 } from 'foolib';
without reaching out to the default variable.

es6 import 'destructuring' not working

Hey there I have this uiTypes.js file like this:
export default {
SELECT_ITEM: 'SELECT_ITEM',
DESELECT_ITEM: 'DESELECT_ITEM',
TOGGLE_ITEM: 'TOGGLE_ITEM',
}
And when I try importing its content like so, it works:
import uiTypes from './uiTypes';
console.log(uiTypes.SELECT_ITEM) // 'SELECT_ITEM'
But not like this:
import { SELECT_ITEM, DESELECT_ITEM, TOGGLE_ITEM } from './uiTypes';
console.log(SELECT_ITEM) // undefined,
Am I missing something?
There is no destructuring for imports (notice also that exports and imports use the keyword as instead of a colon to avoid confusion with objects). You can either import the default export, individual named exports, or the module namespace object.
Your attempt is trying to import three named exports, while there is only a default export; that's why it's failing.
You should use named exports:
export const SELECT_ITEM = 'SELECT_ITEM';
export const DESELECT_ITEM = 'DESELECT_ITEM';
export const TOGGLE_ITEM = 'TOGGLE_ITEM';
or use "real" destructuring after importing the object:
import uiTypes from './uiTypes';
const {SELECT_ITEM, DESELECT_ITEM, TOGGLE_ITEM} = uiTypes;

cannot export const arrow function

new to ES6, I was trying to make a React simple functional component like this
// ./Todo.jsx
export default const Todo = ({
todos,
onTodoClick,
}) => (
<ul>
{todos.map( (todo, i) =>
<li key = {i}
onClick = {() => onTodoClick(i) }
style = {{textDecoration: todo.completed ? 'line-through': 'none' }}
>
{todo.text}
</li>
)}
</ul>
)
But
// Another file
import Todo from './Todos.jsx';
console.log(Todo) // undefined
did not yield the arrow function.
but if I leave off the "const todo =" part in the export link, like so
export default ({
todos,
onTodoClick,
}) => (...)
It gets successfully imported.
Why is that?
You're trying to export a default and declare a variable at the same time, which is invalid syntax.
Consider the following, since we know that you can declare multiple variables using only one instance of the keyword, var a, b, c; the export definition wouldn't make sense at all.
export default var a, b, c;
What would that mean? What would get exported?
Furthermore, using the export default syntax already creates a variable called default that needs to contain a value or reference.
Export the variable instead if you want to make it a constant.
const Todo = () => {};
export default Todo;
There is a thread about this on ESDiscuss
Give it a look
Arrow function export as a separate line:
import React from 'react';
const Body=()=>(
<div>This is my body</div>
);
export default Body;
Here you can export it in the same line
import React from 'react';
export const Body=()=>(
<div>This is my body</div>
);
The important thing is that you must import this arrow function by using below code
import {Body} form 'path';
/*use arrow function name inside the curly bracket only.*/
Hope this will help you to export your arrow function in the same line :)