when to combining multiple imports into a single file - es6-modules

As I understand then combine multiple export statement into a single file is considered a good practice iff source file comes under the same directory
so
import { Observable } from 'rxjs/Observable';
import { Observable, BehaviorSubject, Subject, ReplaySubject } from 'rxjs';
can be re-written to
import { Observable, BehaviorSubject, Subject, ReplaySubject } from 'rxjs';
But what If I have to import only one module than which is preferred way? using a complete file or a specific one.
import { Observable } from 'rxjs/Observable';
OR
import { Observable } from 'rxjs';
does that cost anything extra?
ts v 2.3.4
angular v 4.4.6

import { Observable } from 'rxjs/Observable';
This is the efficient way to import a single module, because you are providing the exact path to only fetch the required module.
Whereas in this case,
import { Observable } from 'rxjs';
It will import a lot of unnecessary stuff from the rxjs library that will increase the page load time and/or the code base.

Related

Create an "Import Menu" in TypeScript

I'm trying to work on a project with a numerous amount of files, and I thought an import object would be helpful. For example, here would be menu.ts on the top-level, which every program will reference to:
import router from "./router/index";
import controllers from "./controllers/index";
import config from "./config";
export default {
router: router,
controllers: controllers
config: config
}
This would be a sample controllers/index.ts:
import database from "./database";
import accounts from "./accounts";
import a_controller from "./a_controller";
export default {
database: database,
accounts: accounts,
a_controller: a_controller
}
Obviously, this would raise some circular dependency issues with controllers referencing to menu. This is asserted with a TypeError: cannot read property controllers of undefined error message. Is there a way to do this?
Thank you for your time.
in your case it is better to use named import, in controllers/index.ts: you can do like:
export { database } from "./database";
export { accounts } from "./accounts";
export { a_controller } from "./a_controller";
and in your menu.ts you can import them like:
import { database, accounts, a_controller } from './controller'

ES6+ export of an import within export default

I'm trying to do this
state.js
export default {
someValue: 'fooBar'
}
index.js
export default {
export {default as state} from './state',
export {default as actions} from './actions'
}
but I am not allowed, Unexpected keyword 'export' (2:2). Is there any way to achieve this?
You can only use import and export at the top level of your module. (You can use dynamic import() elsewhere, but not the static versions.)
So to have that export, you have to do what you've said you're trying to avoid in the comments:
import {default as state} from './state';
import {default as actions} from './actions';
export default {
state, actions
};
but, beware what you're exporting there: an object with state and actions properties whose initial values come from the imported state and action, but which are not connected to them. Code importing that object can change those properties. You could maintain the live binding:
import {default as state} from './state';
import {default as actions} from './actions';
export default {
get state() {
return state;
},
get actions() {
return actions;
}
};
but at that point you're kind of reinventing the module namespace object. You might prefer to simply:
export {default as state} from './state.js';
export {default as actions} from './actions.js';
and then either use those named exports:
import {state, actions} from "./index";
or use the module namespace object
import * as index from "./index";
// Use `index.state` and `index.actions`

Angular How to check HttpRequest object to set proper content-type for headers?

My team is working for some time on rewriting front-end of our application to Angular. Everything was going more or less smoothly until I encountered file importing views. Our default HttpHeaderEnricherInterceptor is setting default Content-Type as application\json. It works well in the whole application but while trying to import any file all I get is 415. However, if I remove .set('Content-Type', 'application/json') importing is working properly... but all other components are failing. I was trying to make some if statements based on HttpRequest params but it doesn't recognize has() method and some others that I've tried.
I know that final option to solve this is to set content-type on each request but it's something I would like, better avoid it as we decided to try finding global solution to the problem.
Here's my intercept() code:
import { TokenService } from './../token/token.service';
import {Injectable} from '#angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '#angular/common/http';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class HttpHeaderEnricherInterceptor implements HttpInterceptor {
constructor(private tokenService: TokenService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(`${req.url}?${req.params.toString()}`);
const changedReq = req.clone(
{headers: req.headers
.set('Authorization', this.tokenService.getToken() || '')
.set('Content-Type', 'application/json')
});
return next.handle(changedReq);
}
}
Thanks for any tips!
Looks like there is already opened issue on Github: https://github.com/angular/angular/issues/19730
Workarounds are possible but ugly, i.e. global boolean flag switching before and after call, adding fake header as indicator i.e.:
if(headers.get('X-Set-Content-Type') != null){
headers.set('Content-Type', 'application/json')
}

'xdom is not defined' error within autopulous-xdom2jso

I have imported below packages in my service, which I use for SOAP-API processing.
"autopulous-xdom": "~0.0.12"
"autopulous-xdom2jso": "^0.0.12"
I am trying to use these with below lines at top of my service.ts
import 'autopulous-xdom/xdom.js';
import 'autopulous-xdom2jso/xdom2jso.js';
import convert = xdom2jso.convert;
import {Injectable} from '#angular/core';
#Injectable()
export class SoapService {
constructor() {}
}
I get no errors on compiling and building. But while running the application in browser, I get below error.
Has anyone worked with xdom2jso and xdom? Please help.
I got no responses and all I could do was fork and raise a PR myself into autopulous-xdom2jso.
See my fix here: https://github.com/autopulous/xdom2jso/pull/2

How to troubleshoot es6 module dependencies?

I am developing a React & Reflux app, which is bundled by webpack with babel-loader (v6), and I am experiencing es6 modules dependencies issues
For example, I have a component that use the reflux .connect() mixin :
import MyStore from '../stores/my-store';
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
When I import all modules individually in each file like this, everything's fine.
I then tried to improve my code by using deconstructed import statements :
...in a component :
//import One from '../js/one';
//import Two from '../js/two';
//import Three from '../js/three';
import { One, Two, Three } from '../js'; // Instead
...and in js/index.js :
import One from './one';
import Two from './two';
import Three from './three';
export { One, Two, Three };
App source code files are more concise using the above technique, because I can import all components in one import line.
But when I use this, some dependencies end up beeing undefined when I use them
If I use the same updated example...
//import MyStore from '../stores/my-store';
import { MyStore } from '../stores'; // Instead
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
...MyStore parameter ends up undefined in Reflux.connect method.
I tried to troubleshoot in the debugger, but I'm not really aware of what's going on with the __webpack_require__(xxx) statements in the generated bundle. There must be a circular dependency that babel-loader or webpack require could not figure out when there are the index.js files re-exporting individual modules.
Do you know any tool that can help me figure this out? I tried madge but it does not work with es6 modules, and I could not find anything that would tell me where anything is wrong
In order to get extended info about build, run:
webpack --profile --display-modules --display-reasons
It will give you bunch of information for optimisation/profiling.
import statement is used to import functions, objects or primitives that have been exported from an external module.
As per MDN doc, you can import the Modules not the directory.
import name from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as alias from "module-name";
import defaultMember from "module-name";
import "module-name";
Reference URL:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
http://es6-features.org/#ValueExportImport
https://github.com/lukehoban/es6features#modules
http://www.2ality.com/2014/09/es6-modules-final.html
As a workaround keep one file as base.js and include all your 3 files.