Classes from TypeScript NPM Package are all bundled in the build result
I created a npm package with multiple TypeScript classes which I want to use on various projects. e.g:
// dog.ts
import Animal from "../animal";
export class Dog extends Animal {
public bark(): void { console.log('bark'); }
}
This is how those classes are exported on the npm package:
// main.ts
export {Dog} from "./animals/dog";
export {Cat} from "./animals/cat";
export {Ape} from "./animals/ape";
I started a blank angular project via ng new my-app
, added the npm package to my project via npm i @farm/animals
and imported the Dog class to the AppComponent:
// app.component.ts
import { Component } from '@angular/core';
import { Dog } from '@farm/animals';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
lassie: Dog = new Dog();
}
What I realized after a production build (ng build --prod
) is that the other exported classes like Cat and Ape are also bundled into the main.js build result. I assumed those would be filtered out by tree shaking mechanisms.
How can I achieve that only the imported classes are put to the build result? Is anything wrong with my export structure?
Thanks in advance!
//edit: I just realized that import {Dog} from '@farm/animals/dist/classes/dog';
does the job as expected. Is there a way to export these classes individually with a nice short name for import?
See also questions close to this topic
-
Angular Material 7 Error Resetting Autocomplete After Form Submit
I have the following material autocomplete field working. The issue is an error I get when resetting the form after successfully submitting data.
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'company' of null TypeError: Cannot read property 'company' of null at MatAutocomplete.push../src/app/expense/expense-new/expense-new.component.ts.ExpenseNewComponent.displayFn [as displayWith] (expense-new.component.ts:93)
for some reason calling
this.expenseForm.reset
completely erases the displayWith directive data to null. Works fine on a fresh page reload.My template:
<mat-form-field class="full-width-input"> <input type="text" placeholder="Pick one" aria-label="Number" matInput formControlName="payee_id" [matAutocomplete]="auto"> <mat-autocomplete #auto="matAutocomplete"> <mat-option *ngFor="let payee of filteredOptions | async" [value]="payee"> {{payee.company + " " + payee.first_name + " " + payee.last_name }} </mat-option> </mat-autocomplete> </mat-form-field>
My submit function:
onSubmit(formData: any, formDirective: FormGroupDirective) { this.expenseForm.value.payee_id = this.expenseForm.value.payee_id.id ; this.expenseService.addExpense(this.expenseForm.value).subscribe( success => { this.errorMessage = null; this.dataService.updateDataTable('new expense success'); this.expense_expense_categories_attributes.controls = []; formDirective.resetForm(); //workaround for error state not resetting this.expenseForm.reset(); }, error => { this.errorMessage = error; console.log(this.errorMessage); this.openDialog(); }); }
Autocomplete Filter Functions:
displayFn(payee?: Payee): string | undefined { if ((payee.company !== '' || null) && (payee.first_name !== '' || null && payee.last_name !== '' || null)) { return payee ? payee.company + ' - ' + payee.first_name + ' ' + payee.last_name : undefined; } else if (!payee.company) { return payee ? payee.first_name + ' ' + payee.last_name + ' ' + payee.company : undefined; } else if ((payee.company !== '' || null) && (payee.first_name === '' || null && payee.last_name === '' || null)) { return payee ? payee.company : undefined; } } private _filter(name: string): Payee[] { const filterValue = name.toLowerCase(); return this.payees.filter(option => option.first_name.toLowerCase().indexOf(filterValue) === 0 || option.last_name.toLowerCase().indexOf(filterValue) === 0 || option.company.toLowerCase().indexOf(filterValue) === 0); }
-
in Angular 4 HttpClient how can I receive status code?
To get data I am doing:
data = this.http.get(url, httpOptions);
But this is only returning the body. I need the entire response to get the status. I know this syntax:
data = this.http.get(url, {observe: 'response'});
But this is replacing my
httpOpttions
which will make me unauthenticated. I can't add another argument onGET
like I can inPOST
. Please help! -
How to modify an angular components input value dynamically
I am using an angular component within the component that I am creating. I cannot modify the component(DogstarComponent) that I am using. It has an input value of "Alive" that I can set to true or false. However, I have multiple DogstarComponents in my html and only want to modify the "alive" input value of the one that I click. Whats the best way to do this? See example pseudocode below.
DogstarComponent.ts import { Component, Input } from '@angular/core'; @Component({ selector: 'dogstar-selector', template: ` <another-Component class="test" [alive]="alive" header="{{title}}"> <ng-content></ng-content> </another-Component> ` }) export class DogstarComponent { //Title @Input() title: string; //alive @Input() alive: boolean = false; }
dogstar-selector is used in a completely different components' (spaceships) HTML
spaceship.component.html
<dogstar-selector (click)="changeAliveValue();" [alive]="true" [title]="test""> <p> information </p> </dogstar-selector>
spaceship.component.ts
@Component({ selector: 'spaceship', templateUrl: './spaceship.component.html', styleUrls: ['./spaceship.component.css'] }) @Injectable() export class SpaceshipComponent implements OnInit { ....... changeAliveValue() { //How do I change the input value of [alive]? }
-
Getting rid of Outer Nested Observable Typescript
I am currently trying to get rid of an Outer Observable. My current code creates an
Observable<Observable<any>[]>
but I am trying to get anObservable<any>[]
type. I've played around with different rxjs operators but couldn't find any that would work. I believe part of my problem is with outer map but I'm not sure how to change that without loosing my inner array.So I have this code
this.userOrgs = this.db.doc(user_preferences/${user.uid}).valueChanges().pipe( map((pref: UserPreferences) => { return pref.orgs.map(org => { return this.db.doc(organizations/${org}).valueChanges().pipe( map((o: Organization) => { return o; }) ); }); }) );
and this.userOrgs is of type
Observable<Organization>[]
; -
Is there a way in TypeScript to use an interface as a guard without losing the specificity of the object?
I have a problem where I am trying to make an interface for shared modules in TypeScript that for the purpose of this question let's assume has the following shape:
interface A { x: string; y: { [name: string]: (...args: any) => {type: string; payload?: any} }; z?: () => any }
The purpose of this interface is two-fold:
- For the person producing the module, I want them to be able to know that the thing they are creating complies to A.
- For the person consuming the module, I want them to be able to have the most specific typing possible.
For example, if I had:
const bar = { x: 'hello', y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) } }
Note the lack of reference to interface
A
.If I were to then type:
bar.
I would get intellisense that it has propertiesx
andy
. Even more though, upon typingbar.y.
I would get prompted thatworld
exists and the function type associated with it.However, if I add in
A
:const bar: A = { x: 'hello', y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) } }
it helps the case of someone accidentally adding a wrong property like:
const bar: A = { iDontBelong: true, // wrong x: 'hello', y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) } }
or even
const bar: A = { x: 5, // wrong y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) } }
The problem is now if someone were to import
bar
and typebar.
they would get suggestions that are directly for interfaceA
. It loses the knowledge thatbar
only hasx
andy
(and noz
), and it also loses the information abouty
's specific type meaning it wouldn't even knowworld
existed ony
.Is there any way to get both of these things to exist at the same time?
-
Filtering ranks using lodash in angular 7
I have an angular app that displays sample data as below:
samples = [ { 'user': 'trump', 'rank': 36, 'active': true }, { 'user': 'fred', 'rank': 30, 'active': false }, { 'user': 'luke', 'rank': 47, 'active': true }, { 'user': 'hillary', 'rank': 44, 'active': false }, { 'user': 'bernie', 'rank': 36, 'active': true }, { 'user': 'john', 'rank': 40, 'active': false }, { 'user': 'pebbles', 'rank': 1, 'active': true } ];
What I wanted to do is that using
lodash
to filter rank in the client. I have filter that allows for me to filter ranking greater than or less than. Here are the filters:In
component.ts
:.... other necessary codes.... ngOnInit() { this.sampleService.loadAllSamples().subscribe(filteredSamples => { this.filteredSamples = filteredSamples; this.applyFilters(); }); } private applyFilters() { this.filteredSamples = _.filter(this.samples, _.conforms(this.filters)); } filterGreaterThan(property: string, rule: number) { this.filters[property] = val => val > rule; this.applyFilters(); } filterLessThan(property: string, rule: number) { this.filters[property] = val => val < rule; this.applyFilters(); }
In my html template, I have the rank filter which allows me to get the ranks greater than entered value.
<input type="number" id="rank" name="rank" [(ngModel)]="rank" (change)="filterGreaterThan('rank', rank)">
So far, everything works as expected. I have the data with filtered (in this case, greater than) displayed.
What I wanted to do is that add another filtering just like above. This one should allow me to filter "less than" at the same time like rank range. My problem is that since both filters targets rank value, I am not able to filter ranks from greater than and less than at the same time. Any help will be appreciated!
-
Uncaught TypeError: PouchDB.plugin is not a function
When i execute the code belove, this error shows up: Uncaught TypeError: PouchDB.plugin is not a function. If i install the pouchdb package from npm and change the first line accordingly, then the plugin part works but if i want to use a function from pouchdb-authentication i getting a function not found error.
const PouchDB = require('pouchdb-browser'); let auth = require('pouchdb-authentication'); PouchDB.plugin(auth);
The code should execute without errors and the functions from the authentication plugin should work.
-
react-loadable higher order component
I'm trying to use react-loadable to implement code splitting, and as suggested in the docs I've created a HOC for it, like this:
export default function({ componentPath }) { return Loadable({ loader: async () => { const component = await import(componentPath) return component; }, delay: 200 }); }
and I use it like this
import withLoadable from "hoc/withLoadable"; .... const Home = withLoadable({componentPath: "containers/Home"});
but I got the following error
Error: Cannot find module 'containers/Home' at eval (eval at ./src/hoc lazy recursive (main.chunk.js:formatted:98), <anonymous>:5:11)
Referring to the docs here, they mentioned this issue and how to solve it, I tried to add the
modules
, andwebpack
attributes but it didn't work.BTW: in webpack.config.js I've added the "src" directory to the resolve modules like this:
... resolve: { // This allows you to set a fallback for where Webpack should look for modules. // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // https://github.com/facebook/create-react-app/issues/253 modules: ['src','node_modules'].concat( // It is guaranteed to exist because we tweak it in `env.js` process.env.NODE_PATH.split(path.delimiter).filter(Boolean) ), ...
I'm sure I miss something, but I can get it ...
-
How can I setup SCSS files (ViewEncapsulated way) in 'react app 2' like Angular component specific SCSS?
I installed 'react app 2' as well as node-sass. It's working fine with SCSS. But I just want to know how can I create component specific SCSS like Angular (that will never be a conflict with other components SCSS)
Angular automatically add an attribute for ViewEncapsulation see below example
In angular, there is an option for
encapsulation: ViewEncapsulation.None (Use to disable CSS Encapsulation for this component) enter link description here