angular / angular-cli

CLI tool for Angular
https://cli.angular.dev
MIT License
26.78k stars 11.98k forks source link

Error with build --prod & templates since angular/cli 1.0 #5623

Closed LapassetAlexis closed 7 years ago

LapassetAlexis commented 7 years ago

Bug Report or Feature Request (mark with an x)

- [x] bug report
- [ ] feature request

Versions.

$ ng --version


/ \ | | / | | | | / ? \ | ' \ / ` | | | | |/ ` | '| | | | | | | / | | | | (| | || | | (| | | | |__| | | | // __| ||_, |_,||_,|| __|__|| |/ @angular/cli: 1.0.0 node: 6.9.2 os: win32 x64 @angular/common: 2.4.10 @angular/compiler: 2.4.10 @angular/core: 2.4.10 @angular/forms: 2.4.10 @angular/http: 2.4.10 @angular/platform-browser: 2.4.10 @angular/platform-browser-dynamic: 2.4.10 @angular/router: 3.4.10 @angular/cli: 1.0.0 @angular/compiler-cli: 2.4.10

Repro steps.

ng build all is OK ng build --prod is KO since morning after update to angular/cli 1.0

I have one class Field with attributes :

export class Field {
    key: string;
    type: string;
    label: string;
    order: number;
    fields: Array<Field>;
    validators: FormValidators;
    attributes: Attributes;
}

And this :

export class Attributes {
    canBeCreated: boolean;      // Apparait dans le formulaire de création
    canBeEdited: boolean;       // Apparait dans le formulaire de modification
    canBeFiltered: boolean;     // Apparait dans les filtres
    canBeSorted: boolean;       // Permet le tri sur la colonne
    isInList: boolean;          // Apparait dans la liste
    isInDetail: boolean;        // Apparait dans le détail
    placeholder: string;        // Texte qui apparait quand le champ est vide lors de la création ou modification

    constructor (attr: Attributes) {
        this.canBeCreated = attr && attr.canBeCreated ? attr.canBeCreated : true;
        this.canBeEdited = attr && attr.canBeEdited ? attr.canBeEdited : true;
        this.canBeFiltered = attr && attr.canBeFiltered ? attr.canBeFiltered : true;
        this.canBeSorted = attr && attr.canBeSorted ? attr.canBeSorted : true;
        this.isInList = attr && attr.isInList ? attr.isInList : true;
        this.isInDetail = attr && attr.isInDetail ? attr.isInDetail : true;
        this.placeholder = attr && attr.placeholder ? attr.placeholder : '';
    }
}

export class CheckboxAttributes extends Attributes {
    options: Array<{label: string, value: string}>;  // Liste des valeurs possibles de les checkbox
    isBinary: boolean;                               // Choix true/false ou multiple

    constructor(attr: CheckboxAttributes) {
        super(attr);
        this.options = attr && attr.options ? attr.options : null;
        this.isBinary = attr && attr.isBinary ? attr.isBinary : false;
    }
}

In my component checkbox.component.html :

    <div *ngIf="!field.attributes.isBinary">
         .....
    </div>

The log given by the failure.

ERROR in C:/Users/LAPASSAL/Projects/marty/src/$$_gendir/app/generic/components/checkbox-input/checkbox-input.component.ngfactory.ts (377,66): Property 'isBinary' does not exist on type 'Attributes'.
C:/Users/LAPASSAL/Projects/marty/src/$$_gendir/app/generic/components/checkbox-input/checkbox-input.component.ngfactory.ts (380,61): Property 'isBinary' does not exist on type 'Attributes'.

In typescript can I cast the object type to CheckboxAttributes with (this.field.attributes as CheckboxAttributes).isBinary ? false : [] but how can I do this in template? Any idea ?

Thx

elvisbegovic commented 7 years ago

thanks to team for this breakin change

emreavsar commented 7 years ago

so, everybody is complaining about these problems, but nobody provides a solution?

what's the best practice here?

thanks

elvisbegovic commented 7 years ago

it's simple, aot require all members you use outisde your class be public. But this cli console, doesn't tell us before relase! Team forget people using cli since a while with big project, response: we have to KNOW that for aot all members are public !

I can say too:

we have to know that when using var a:number = "bonjour" will throw error why show it in console ? LOL

maybe now cli is good, but before release cli was 💩

xiluo58 commented 7 years ago

Is there a tool to check this kind of error? I remember ng lint reports these errors before, but doesn't do it now. I am using @angular/cli 1.0, default dependencies versions and default settings.

basst314 commented 7 years ago

I'm also looking for a best practice here. In addition to @emreavsar 's suggestions it would also be reasonable to

This aligns pretty well with common encapsulation conventions with the only downside to write a little more code.

webcat12345 commented 7 years ago

Thanks for your comment @basst314. But Too many codes should be modified. That is not good option. Anybody please let me know the version of dependencies I can use without any modification.

{
  "name": "ng-reason",
  "version": "0.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/cli": "^1.0.0-rc.4",
    "@angular/common": "~2.4.4",
    "@angular/compiler": "~2.4.4",
    "@angular/core": "~2.4.4",
    "@angular/forms": "~2.4.4",
    "@angular/http": "~2.4.4",
    "@angular/platform-browser": "~2.4.4",
    "@angular/platform-browser-dynamic": "~2.4.4",
    "@angular/router": "~3.4.4",
    "@types/google-maps": "^3.2.0",
    "angular2-tag-input": "^1.2.1",
    "core-js": "^2.4.1",
    "ng2-bootstrap": "^1.2.6",
    "ng2-bs3-modal": "^0.10.4",
    "ng2-map": "^0.16.3",
    "ng2-table": "^1.3.2",
    "rxjs": "5.2.0",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@types/jasmine": "^2.2.30",
    "@types/node": "^7.0.0",
    "@angular/cli": "^1.0.0-rc.4",
    "codelyzer": "~3.0.0-beta.4",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "3.2.0",
    "karma": "1.5.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-remap-istanbul": "^0.6.0",
    "protractor": "5.1.1",
    "ts-node": "2.1.0",
    "tslint": "4.5.1",
    "typescript": "2.2.1"
  }
}

Here is my package.json. Thanks.

edemirkan commented 7 years ago

@basst314 getters/setters are fine if there's a business requirement to modify underlying private property. Apart from that, just for template binding - get/set creation is somewhat overkill.

  private _authenticatedUser$: BehaviorSubject<IAuthenticatedUser> = new BehaviorSubject<IAuthenticatedUser>(null);

  public get user(): Observable<IAuthenticatedUser> {
    return this._authenticatedUser$ as Observable<IAuthenticatedUser>;
  }
basst314 commented 7 years ago

What would you suggest @demirk4n ? Somewhat the decision has been made that the template is not part of the component (somehow weird for me), so private variables are not accessible. Making everything public doesn't feel right to me (coming from Java world).

elvisbegovic commented 7 years ago

You seems don't know how template and class are connected. For me there is sens to have it punlic only reclamation goes to cli that doesn't inform us with error in console !

@basst314

edemirkan commented 7 years ago

@basst314 I'd just use public properties for basic template stuff and getter/setters to wrap around a more complex business logic for a private property.

One can hope, maybe in the next iteration of ES Microsoft may surprise us with a C# get/set functionality :)

public string Name { get; set; }

which will be equal to

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
thaihacong commented 7 years ago

It seems that Angular 4.0 is not able to recognize the local variable inside ngFor loop.

<div class="row" *ngFor="let employee of employees; let i = index; trackBy: employee?.uuid">
  <employee-details [id]="generateId(employee.date)" [(employee)]="employees[i]">
  </employee-details>
</div>

ng build --prod returns

ERROR in ng://../src/app/employees.component.html (175,32): Property 'employee' does not exist on type 'EmployeesComponent'.

In EmployeesComponent, I declared employees: Employee[];, but not employee: Employee. This worked well before without such warning messages.

UPDATE: If I remove trackBy: employee?.uuid, ng build --prod is OK.

So, the problem could be related to trackBy in this case.

harilal commented 7 years ago

@thaihacong https://toddmotto.com/angular-ngfor-template-element

i think these needs to be as directives.

thaihacong commented 7 years ago

@harilal I updated my comment. The problem could be related to trackBy.

elvisbegovic commented 7 years ago

trackBy is now function! how you use trackBy is bad. please check docs it's function that retunr id Cheers

@thaihacong

hansl commented 7 years ago

I'm locking this discussion down. The original issue is being worked on and the discussion is getting a bit out of hand here.

hansl commented 7 years ago

@alapasset Regarding your original issue:

The following code in Typescript will not compile:

interface A {
  aValue: number;
}
interface B {
 aValue: number;
 bValue: string;
}

function a(aOrB: A | B): string {
  const x = aOrB.aValue;  // Valid. aValue is part of both interfaces.
  const y = aOrB.bValue;  // ERROR. bValue is not part of A.
}

a({ aValue: 1 });

I think this comes from a misunderstanding of what the A | B typing does. It's not valid to use either types as if the value passed in is either. You can only use properties that are part of both typings, since you don't know which one is passed.

You need to change your typings to reflect the code, or typecast it if possible.

I'm going to close this issue. I have a PR to move warnings in templates as warnings, but it's not a fix for this issue.

hansl commented 7 years ago

https://github.com/angular/angular-cli/pull/5698 fixed typescript messages and warnings to not be considered errors. Please note this will not remove errors from your templates from being reported.