Skip to content

Instantly share code, notes, and snippets.

@NullVoxPopuli
Last active July 9, 2020 08:12
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NullVoxPopuli/82ee489121fcc21a0e80aaf88559dada to your computer and use it in GitHub Desktop.
Save NullVoxPopuli/82ee489121fcc21a0e80aaf88559dada to your computer and use it in GitHub Desktop.
Anti Patterns (and things I don't like) in Angular2

General

Templates written a giant string in components.

This tutorial demonstrates this: https://angular.io/docs/ts/latest/tutorial/toh-pt1.html you don't get syntax coloring, or any benefits you'd get from a good html/templating tool.

(( flashbacks to inline html strings in C++ ))

Tag bloat with ngDirectives (such as ngFor)

from an angular.io example:

<li *ng-for="#el of list; #idx = index" [style.font-weight]="el.generation == generation && generation > 0 ? 'bold' : 'normal'">

Things that make refactoring a PITA

Component Importing (import, add to directives, then use (too much coupling))

Ember allows components to be called from the templates.

e.g.:

{{component-name var=value}}

or

{{folder/component-name var=value}}

Everything requires an absolute path (img srcs, template files, etc)

static assets don't have special treatment, so in your index.html, you may have something like:

  <link href="app/ui/assets/styles/application.css" rel="stylesheet">

it should be just:

  <link href="application.css" rel="stylesheet">

But angular-cli doesn't actually compile anything when it builds the dist directory. (keeping the dev folder/file structure) Even when doing ng build -prod, your dist directory still has the entire app folder structure..

Specifying a tag name for each component (de-couples name from component)

This is especially a problem when rendering tables.

if you want to use a component as a table-row, you need to specify the selector as an attribute of tr. e.g.: <tr component-name>.

For this type of component, it should be possible to specify the tagname that the component renders as. for example, tr.

so, when rendering a table, you'd just do:

<table>
  <thead>
   {{header-row}}
...

Things I don't like about angular

Conventions?

The angular communitive actively avoids specifying conventions, making it next to impossible to automate things (without having to build your own build process. Angular-CLI is kind of addressing this, but very lightly. there is still a ton of manual work to be done, especially when it comes to routing, static assets, and 3rd party libraries.

No Data Persistence Package / recommendations

Because of this, there isn't a way to easily have many models. (very not scalable)

Angular should have a blessed data library that it supports and maintains. Data is too common of a problem to ignore this.

Typescript

This is more of an issue with static typing in a dynamic world than with typescript itself, but for managing large amounts of models, it's easier to have them all auto-loaded, and then dynamically interacted with (like with ember-data), rather defining a typed interface for each model.

no import references by app-level absolute path.

Ever had import {...} from '../../../../../../../component-name'? being able to say .. from '@appName/component-name' would be much nicer

I asked angular/angular-cli about this: angular/angular-cli#865 Currently, it either can't be done, or no one knows how / it isn't documented.

Template paths must be absolute (problem when refactoring)

I have found actually that if your template is in the same folder as your component, you can do this:

@Component({
  moduleId: module.id,
  templateUrl: 'template.html',
  ...

which helps, but I feel like it should still be implicit.

no recommended project structure

There is a loose guide in the angular styleguide, but it doesn't cover anything complicated, leaving teams to come up with their own structure. I've adopted Ember's module unification RFC.

no default templating language

HTML isn't a templating language, and how angular interacts with it feels like a hack.

rather than doing

{{item-summary 
  *ngFor="let item in collection" 
  *ngIf="item.isTrue"
  [model]="item"
}}

I'd rather do:

{{#each item in collection}}
  {{#if item.isTrue}}
    {{item-summary model=item}}
  {{/if}}
{{/each}}

docs and recommended examples have multiple classes in a file.

This is just lazy coding / design.

ngIf can't be used with bound properties (it's recommended to use ngShow / ngHide).... -.-

ngIf creates its own context, which breaks data binding. If you want something to hide/show based on the status of a property, that markup must always be in the dom via ngShow/ngHide.

dependencies have to be included in 4 places.

This is the recommended way to use 3rd party libraries.

Add a reference to:

  • packages.json
  • angular-cli-build.js
  • system-config.js#map
  • system-config.js#packages

What angular needs is an addon system that people can develop addons for angular, so people could just do ng install addon-name, and nothing else. For non-angular specific addons, maybe such as momentjs, they could use bower, and add a single reference to angular-cli-build.js.

@MrJerB
Copy link

MrJerB commented May 25, 2016

I loved Angular 1 and still use it at work but I slowly started using Angular 2 for my fun home projects... until I came across ember that is!

@Martinspire
Copy link

Wholeheartedly agreeing with this. Currently it doesn't seem faster, it doesn't seem easier and it doesn't seem simpler/shorter. So why the hell would i switch or even start looking right now? I wouldn't be surprised if some of the mechanics completely change in the near future or that people will pick up the AngularJS 1 project and fork it into something else to keep maintaining it. I seriously don't understand why one would choose ng2 right now (or soonish). Not to mention that everything has to start from absolute zero. No reusing of old plugins, old tutorials and old editor addons. Everything has to be made from scratch and there isn't a group leading the way right now. Everybody is doing something (or the same thing: building hello world apps).

@Aetherus
Copy link

Aetherus commented Jan 20, 2017

There's one thing I don't like angular 2: too many imports. In angular 1 + sprockets, whenever I want to use a service, I only need to import it once. For controllers and directives, I don't have to import them at all.

angular.module('app').controller('someController', ['someService', function(someService) {...}])

But in angular 2, I have to import it 3 times!

import { SomeService } from './some.service'  // <---- once

@Component({
  providers: [SomeService]  // <---- twice
})
class SomeComponent {
  constructor(private someService: SomeService) {}  // <---- thrice
}

And I have to import components too. That's too many imports, too many boilerplate codes with no real benefit. I feel like I'm importing something so that it can be imported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment