cannot export const arrow function - ecmascript-6

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 :)

Related

Inject image/svg/whatever in an angular template with cache hash handling

Having an assets folder with :
/assets/images/image1.png
/assets/svg/svg1.svg
How to include it in an HTML template (not in a CSS file) in order to have angular/webpack to automatically enable cache-busting on it (transforming automaticallt assets/images/image1.jpg to assets/images/image1-4d5678xc0v987654v.jpg?
The goal is to handle cache and refresh it soon ASAP when an existing file gets updated.
With webpack, I used to do a :
<img src="<%=require("./assets/img/image1.jpg")%>" />
The only solution I found with angular is requiring all my images in the .ts file but it's quite a pain to do :
const image1src = require(`../assets/images/image1.jpg`);
class Component {
image1 = image1src; // contains image1-4d5678xc0v987654v.jpg
}
// and in template : <img [src]="image2" />
Is there something simplier ?
ps: I don't want to handle a query paremeter or custom name myself
pps: I don't want to inject these files through CSS (and I know it works when files are getting injected by css)
ppps: using a PWA is not an option in my case
Thanks
I created a pipe for this so I don't need to create variables inside a component as you did.
import {Pipe, PipeTransform} from '#angular/core';
#Pipe({
name: 'imgURL'
})
export class ImgURLPipe implements PipeTransform {
transform(value: string): string {
return require('../../../images/' + value); // specify here a correct src to your folder with images
}
}
To make the require works inside components or pipes, add this to your typings:
declare var require: {
<T>(path: string): T;
(paths: string[], callback: (...modules: any[]) => void): void;
ensure: (
paths: string[],
callback: (require: <T>(path: string) => T) => void
) => void;
};
Inside a template, it looks like this:
<img [src]="'myImage.png' | imgURL">
Remember to add a declaration of the pipe to your module.
are you using angular-cli?
Check this article, it explains how to manage the assets with angular-cli: https://kimsereyblog.blogspot.com/2017/09/manage-assets-and-static-files-with.html
Other solution would be to use css, eg:
background: url('../assets/fonts/roboto-v15-latin-regular.svg')

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.

ES6 member import not working, but default import works

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.

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;