Basic questions about Rxjs - javascript

Im developing a small app with angular2 and I installed Rxjs 5.
In every tutorial there is a diffrent way to import the Rxjs libary.
The code to import in angular2 web is not working; I mean that Websotrm doesn't recognize Observable or any of its functions (from,subscribe,...).
What do I need to do to fix that?
If I import everything from Rxjs, does the load of the website will be slower? (I won't have more then 2- classes)
(Webstorm question) How to I make webstorm to autocomplete the name of the functions with out pressing alt+space

The latest RXJS distributions offer broken up modules to mitigate the gigantic filesize, à la Lodash. Importing rxjs/Rx (as another answer suggests) will get you the entirety of the library and isn't suggested.
Instead, import methods and operators individually:
for core classes, import the class from its scoped module: import { Observable } from 'rxjs/Observable'
for instance methods, use the instance scope in the "add" scope: import 'rxjs/add/observable/fromEvent' (note there is no destructured object to import – the method is added automatically by the import)
for operators, import from the add/operator scope: import 'rxjs/add/operator/switchMap'
Importing an operator once makes it available to all instances, so it's recommended to gather all the parts you use in a single file and import that file wherever needed, I.E. by re-exporting the instances you use.
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/flatMap';
import 'rxjs/add/operator/switchMap';
export { Observable, BehaviorSubject };

This works in my projects: import {Observable, Subject} from "rxjs/Rx";
You only need to add Rx.umd.min.js from rxjs/bundles. It's about 170KB.
Try upgrading to WebStorm 2016.2. I am using that version and it works fine (provided you have the correct imports) Has better support for Angular 2 in general. See change notes.
I virtually never use Ctrl+Space. Tip: Set the Autopopup code completion value (Settings, Editor, Code Completion) to a very low delay.

Related

When do I use {} and when do I not in import in JavaScript [duplicate]

This question already has answers here:
When should I use curly braces for ES6 import?
(11 answers)
Closed 1 year ago.
I am learning Vue JS and find that sometimes we import {} sometimes we import without {}. What is the difference, please?
import Home from '#/views/Home.vue'
import { createRouter, createWebHistory } from 'vue-router'
Thank you
The import with {} is called named import and without {} is called default import.
When you export a component as export Component_Name you import it as import {Component_Name } from 'path_to_component';
When you export a component as export default Component_Name you import it as import Component_Name from 'path_to_component';
It's nothing vue specific, it's just a feature of ES6 version of Javascript.
If you want all or more function(component) of the package you can use import Home from '#/views/Home.vue',
If you want a specific function(component) from the package you can use import { createRouter, createWebHistory } from 'vue-router'
To my mind, the way Javascript does imports is confusing, and is a common source of programming errors.
The problem is that there are no rules about default exports vs named exports, and there are no errors that come from importing the wrong thing.
For example,
import moment from 'moment' // The _right_ way to import it
const now = moment()
Compare that with this code, which looks remarkably similar, only the braces on the import are different:
import { moment } from 'moment' // The _wrong_ way to import it,
// but it doesn't throw an error (until you try and use it)
const now = moment() // Will throw an error, because moment is undefined
There is a good article here on the subject: https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/
Conclusion
I’ve had several productivity problems importing default
exports in my projects. While none of the problems are necessarily
impossible to overcome, using named imports and exports seems to
better fit my preferences when coding. Making things explicit and
leaning heavily on tooling makes me a productive coder, and insofar as
named exports help me do that, I will likely favor them for the
foreseeable future. Of course, I have no control over how third-party
modules I use export their functionality, but I definitely have a
choice over how my own modules export things and will choose named
exports.

How to export a submodule in a Typescript library

So my goal is to create a library in Typescript. My intention is to split up core parts of the library into submodules like RxJS or Angular Material.
RxJS and Angular both support imports like so:
// RxJS
import { map, filter } from 'rxjs/operators';
// Angular
import { MatButtonModule } from '#angular/material/button';
However, I am unable to replicate this myself.
My goal is to do something similar and allow you to import a class with import { foo } from 'package/bar;
I have looked at RxJS's source on Github and have tried replicating what they've done but it's not working.
The library compiles fine but when I go about importing it I always get a Cannot resolve dependency 'package/foo' error.
Meanwhile doing import { test } from package (without the submodule part) works completely fine.
I've tried using paths in tsconfig to no avail. If that is the answer then I'm doing it wrong.
How do I go about doing this?
In order to achieve that, you can create your "sub-modules" in different directories (although they are technically part of the same module), and create an index.ts on each of those directories exporting there whatever you want to publish.
For example, I have done this in my NodeJs package Flowed, and you can for example do this:
import { FlowManager } from 'flowed/dist/engine';
Where the corresponding index.ts file is this one if you want to check.
Although in my case I put also available all the stuff from the root, so the previous line would be equivalent to:
import { FlowManager } from 'flowed';

import ES6 modules with Angular and rxjs

There's something I'm not sure to understand with ES6 modules, especially when it comes to import with side effects.
For example, in an Angular project, I'm using Rxjs library to use observables. I need to import functions and objects from this library with ES6 import.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
//later in the code I'm using these imports like this in a method
return Obserable.of(....);
My problem is with imports :
import { Observable } from 'rxjs/Observable'; seems understandable: I'm importing Observable object from 'rxjs/Obserable' located in node_modules.
My problem is with import 'rxjs/add/observable/of';
Why not something like import { of } from 'rxjs/....';
I've read import '...' doesn't export any object or function. What does it do exactly ? If you are not exporting 'of' operator, how can you use it ?
When to use import */import {} from or directly import '...';
Thanks
That's actually old way to import operators.
import 'rxjs/add/observable/of'; is actually prototyping method of to Observable. When you import that, every Observable object has of method available. That's why you should put those import lines in a root file like app.module. However, as I told you at the beginning, it is the old way.
With RxJs 5.5, pipeable operators came into play. You can and should import operators/observables as follows
import { of } from 'rxjs/observable/of';
const myObs = of('some value');
With this way, operators and observables became tree-shakable. Webpack will not put unused operators into your output bundle.
Update
Let's say you are using bunch of operators and you added static imports in a global file. After a while, you refactored your code and you are no longer using Observable.of. But let's say you forgot you already imported that in a global file. Even though you are not using of anymore, you are still going to get the code of of observable in your output bundle. Prototyping makes it impossible to tree shake your code. I suggest you watch this. Ben Lesh explains pipeable operators and RxJs6.

Why do Angular docs suggest importing both on module and on component level?

In the docs for reactive forms, it's suggested that I should add the following lines to my app.module.ts.
import { ReactiveFormsModule } from '#angular/forms';
...
#NgModule({ imports: [ ReactiveFormsModule, ... ], ... })
export class AppModule { }
Then, in a later section, it's suggested to also add the following in my actual.component.ts.
import { FormControl, FormGroup } from '#angular/forms';
I've tried to skip the module part and only import stuff in the component, which seems to work, as far I can tell. It seems reasonable to me that if I'd do the opposite and added the module part, I wouldn't have to import in the components of that module. It's the combination of module part and component part that confuses me.
I don't understand the purpose of the both operations together. Why do they do that?
Importing at module level allows you to declare that module as a dependency of your module hence being able to use its providers, directives, pipes and other stuff in your templates.
Importing at component level allows you to use those classes in your typescript code.
Further explanation
In angular importing a module "merges" that module, so that when your template is compiled it recognizes template elements (components, directives and pipes) as angular elements.
In typescript and javascript in order to use code (classes, functions, constants) that is declared in another file or module you need to import it, in node you use the require() function, in typescript the import from expression.
So if you look at your code you will realize you are importing two different things, the module and the class, the first in order to merge that module and the second in order to use that class.\
Update
In typescript it is possible to have index files which are usually used to export elements whithout having to go deep into the folder structure, the file for '#angular/forms' exports the following (among other things):
export {AbstractControl, AbstractControlOptions, FormArray, FormControl, FormGroup} from './model';
export * from './form_providers';
Where form_providers has the declaration of FormsModule and ReactiveFormsModule.
Hence you are able to import both your module and your classes from one file.
In simple words :
Importing the module allows you to use the features of the module. Reactive forms allow you to create FormGroups with FormBuilders, that contain FormControls.
Importing the features in the component allows you to use those features. If you don't do it, your IDE won't know what FormGroup or FormControl means.
It may work without importing the features because they have been loaded in a bundle, but if you try to build your application without importing them, an error will be thrown.
Also, you need to import modules where you want to use their features. In Angular, modules don't inherit from their parents, so if you import the module at a too high level, you won't have access to it.

import asynchronously in typescript

I need to import an AMD module written in javascript using System.js in a typescript class (Angular 2). I was able to load the library asynchronously using:
System.import('export_name').then(function(instance){
// deal with instance
};
But I need to solve this import synchronously instead of async since the object gets requests before the import is solved (for example, if I put it in the constructor).
I would like to do something like:
import * as [instanceName] from 'export_name';
But it tells me that it is not a module. Any idea how to resolve this?

Categories