One framework. Mobile & desktop.

Overview

Angular - One framework. Mobile & desktop.

angular-logo
Angular is a development platform for building mobile and desktop web applications
using Typescript/JavaScript and other languages.

www.angular.io

Contributing Guidelines · Submit an Issue · Blog

CI status   Angular on npm   Discord conversation


Documentation

Get started with Angular, learn the fundamentals and explore advanced topics on our documentation website.

Advanced

Development Setup

Prerequisites

Setting Up a Project

Install the Angular CLI globally:

npm install -g @angular/cli

Create workspace:

ng new [PROJECT NAME]

Run the application:

cd [PROJECT NAME]
ng serve

Angular is cross-platform, fast, scalable, has incredible tooling, and is loved by millions.

Quickstart

Get started in 5 minutes.

Ecosystem

angular ecosystem logos

Changelog

Learn about the latest improvements.

Upgrading

Check out our upgrade guide to find out the best way to upgrade your project.

Contributing

Contributing Guidelines

Read through our contributing guidelines to learn about our submission process, coding rules and more.

Want to Help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for contributing and then check out one of our issues labeled as help wanted or good first issue.

Code of Conduct

Help us keep Angular open and inclusive. Please read and follow our Code of Conduct.

Community

Join the conversation and help the community.

Love Angular badge

Love Angular? Give our repo a star ⬆️ .

Comments
  • RFC: <proposal #someId [bind]=">

    RFC:

    Update from @IgorMinar on 2014-11-10:

    To summarize the constraints, the solution we are looking for must match the following:

    1. Be valid HTML (see this issue for discussion about [, ], (, ) chars in attr name of valid html).
    2. Be Web designer friendly
    3. Interoperable with web-components (don't interfere with web component initialization)
    4. Support debugging story via inspecting rendered DOM during development
    5. The syntax must clearly distinguish between 1) string literal; 2) expression (binding); 3) expression (events) 4) declaration of variables. All of this must be clear from template without understanding which directives are active or what the internal semantics of these directives are.
    6. Support additional info or options for each binding in order to avoid directive specific micro-syntaxes (this enables for tooling to work without hardcoding support for micro-syntaxes). This must be supported in a way that preserves constraint no. 5.

    Please don't propose any new solutions that don't meet all of the criteria above.


    Original description:

    Current proposal for Angular2 syntax is

    <element #someId [bind]="expr" (event)="doWork()">

    There are several issues with this proposal which have come to light recently. These are:

    element.setAttribute('[foo]', 'exp') does not work.

    In all browsers tested (Chrome, IE, Safari) the above is an error. This means that it is not possible to create a valid template programatically. It is still possible to parse and read the template.

    It seems like that calling setAttribute requires first character to be a-z|_ specifically - is not allowed as starting character nor are any of these ~!@#$%^&*(){}.

    Third part HTML shorteners don't support non-standard characters.

    Tools such as Slim, Haml, JADE don't support generating special characters. This would break the backend servers such as Ruby on Rails.

    SVG requires valid XML and []()# is not valid XML.

    This seems to be in the spec, but at least Chrome browser does not have issues with these characters. Need to investigate more.

    Straw-man Proposal

    We go back to slightly longer text based syntax

    <element var="someId" bind-value="expr" on-event="doWork()">

    The caveat is the ng-repeat syntax, which requires a parameter

    <ul>
      <li bind-ng-repeat--item="items">{{item}}</li>
    </ul>
    

    Why the weird ng-repeat syntax? We want ta make sure that all bindings starting with bind- have right hand side as a valid expression. item in items is not a valid expression, it is a micro syntax. For this reason we need a way to pass the local-var-name into ng-repeat as a string literal, and not as an expression. Hence the ng-repeat--<local-var-name-literral>="expression".

    Please leave your thoughts here.

    Background

    The reasoning behind the new syntax can be found here: https://docs.google.com/document/d/1kpuR512G1b0D8egl9245OHaG0cFh0ST0ekhD_g8sxtI/edit#heading=h.xgjl2srtytjt

    opened by mhevery 352
  • [i18n] plans

    [i18n] plans

    Here is the list of features / fixes planned for i18n.

    If you want new i18n features to be added to Angular, don't hesitate to ask below and I'll let you know if that's feasible and if you should open an issue for it. If you have a bug, open an issue (no need to discuss about it here).

    For Ivy

    Note: runtime translations and most of the new features will only be available with ivy

    Features

    • [ ] Runtime i18n (one bundle for all locales with AOT) - [working on it]
    • [ ] ID migration tool (for when we break ID generation) - [PR #15621]
    • [ ] Use translation strings outside of a template - #11405 - [working on it]
    • [ ] Generate the same ID for xmb/xlf - #15136 [breaking change PR #15621]

    Issues

    • [ ] Ignore ph/ICU expressions when generating i18n ids - #15573 [breaking change PR #15621, blocked]

    Not prioritized

    Features

    • [ ] Allow ICU messages in attributes - #21615 [blocked, requires an update of the parser]
    • [ ] Improve Html Parser (add a new INTERPOLATION_TOKEN to the lexer output for interpolations) - #9340
    • [ ] Opt out of translation (use translate="false" attribute) - #7814
    • [ ] I18nPluralPipe should localize numbers when using "#" - #11761
    • [ ] ICU plural format (add offset & #) - #9117 [blocked, requires "Allow escaping ICU messages - #9286"]
    • [ ] Implement ICU ordinal messages
    • [ ] Auto detect TRANSLATIONS_FORMAT - #11695
    • [ ] Providing TRANSLATIONS at NgModule level - #11431
    • [ ] Add scientific number pipe - #18276
    • [ ] Opening the API - [PR #14281]
    • [ ] Throw during i18n extraction if two different contents have the same @@id - #18272

    Issues

    • [ ] Ignore leading and trailing spaces - #13114
    • [ ] allow numbers for select-icu - #17799
    • [ ] Allow escaping ICU messages - #9286 [blocked, requires an update of the parser]
    • [ ] Template Parser: Error when passing object literal as pipe parameter - #9571
    area: i18n 
    opened by ocombe 310
  • Proposal: Input as Observable

    Proposal: Input as Observable

    Sorry, I'm not good at English.

    @Input property values are provided by parent component. The changes come asynchronously. And if Input property was changed in the child component (it has the property as own property) , its change detector never notice it.

    Goal

    • Parent's input data and child's input property should be synchronized.
    • Developers should understand that input properties are changed asynchronously.

    Proposal

    @Component({ selector: "child" })
    class Child {
      @Input("input") inputValue: Observable<T>;
    
      ngOnInit() {
        this.inputValue.map((value)=>...);
      }
    }
    
    @Component({
      template: `
      <child [input]="valueToChild"></child>
      `
    })
    class Parent {
      valueToChild: T;
    }
    

    Above code does not work. Currently, to receive input as Observable<T>, I must write it like below.

    @Component({ selector: "child" })
    class Child {
      @Input("input") inputValue: Observable<T>
    }
    
    @Component({
      template: `
      <child [input]="valueToChild"></child>
      `
    })
    class Parent {
      valueToChild: Observable<T> = new Observable<T>((observer)=>{
        ...
        observer.next(val);
      });
    }
    

    Example: http://plnkr.co/edit/BWziQygApOezTENdTVp1?p=preview

    This works well, but it's not essential. Parent's input data is a simple data originally.

    I think this proposal make us happy.

    Thanks.

    feature state: Needs Design area: core core: inputs / outputs cross-cutting: observables feature: under consideration 
    opened by lacolaco 297
  • Ivy Renderer (beta)

    Ivy Renderer (beta)

    Overview

    Ivy is a new backwards-compatible Angular renderer focused on further speed improvements, size reduction, and increased flexibility.

    Ivy is currently not feature complete, but can be tested via enableIvy: true angularCompilerOptions flag.

    We currently expect Ivy to remain behind the flag until it's feature complete and battle tested at Google. In the meantime you can check out this Hello World demo.

    To see status of Ivy implementation go here.

    Related Issues:

    feature 
    opened by IgorMinar 211
  • i18n: Able to use translation strings outside a template

    i18n: Able to use translation strings outside a template

    I'm submitting a ... (check one with "x")

    [x] feature request
    

    Current behavior https://github.com/angular/angular/issues/9104#issuecomment-244909246

    I don't think it is possible, like I said before it only works with static text, it won't parse text on the js code, only templates

    Expected/desired behavior Be able to translate strings used anywhere in the code, using an API.

    Reproduction of the problem

    What is the expected behavior? I'm referencing the usage of $translate.instant to exposure real use cases:

    • Custom rendered text:
    if (data._current_results === data._total) {
                    content = this.$translate.instant('CLIPPINGS__LIST__SUMMARY_ALL', {'num': data._current_results});
                } else {
                    if (undefined === data._total) {
                        data._total = '...';
                    }
    
                    content = this.$translate.instant('CLIPPINGS__LIST__SUMMARY', {
                        'num': data._current_results,
                        'total': data._total
                    });
                }
    
                // Put 'mentions' first
                data = angular.merge({}, {
                    mentions: mentions
                }, data);
    
                _.each(data, (value:number, key:string):void => {
                    if (value) {
                        details += value + ' ' + this.$translate.instant('CLIPPINGS__LIST__SUMMARY_TYPE_' + key) + ', ';
                    }
                });
    
                if (details) {
                    details = '(' + _.trim(details, ', ') + ')';
                }
    
                content = content.replace(':details', details);
    

    More examples:

    - Getting image's file name from exported image of a HTML rendered report:
    getExportImageName(hideExtension:boolean):string {
            let fileName:string;
    
            fileName = this.$translate.instant('D_CHART_FACET_authors__EXPORT_FILENAME', {
                'profileName': this.ExportService.GetProfileName(),
                'period': this.ExportService.GetPeriodString(this.SearchFilter.GetPeriodFromInterval())
            });
    
            if (!Boolean(hideExtension)) {
                fileName += '.png';
            }
    
            return fileName;
        }
    
    • Sometimes you're translating, sometimes use model data (could be very verbose in a template):
    private _getTitle():string {
            if (this.inShareColumn) {
                return this.$translate.instant('COMPARISONS__SHARE_COLUMN_share_of_voice_TITLE');
            } else if (this.inTotalsColumn) {
                return this.$translate.instant('COMPARISONS__TOTAL_COLUMN_share_of_voice_TITLE');
            } else {
                return _.get<string>(this.group, 'profileName', '');
            }
        }
    
    • Using a third party chart plugin (Highcharts)
    this.chart = new Highcharts.Chart(<any>{
                title: {
                    text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone').toUpperCase(),
                },
                xAxis: {
                    title: {
                        text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone_xaxis')
                    }
                },
                yAxis: {
                    min: 0,
                    title: {
                        text: this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_TITLE_tone_yaxis')
                    }
                },
                plotOptions: {
                    scatter: {
                        tooltip: {
                            headerFormat: '<b>{point.key}</b><br>',
                            pointFormat: '{point.y} ' + this.$translate.instant('REPORTS_BLOG_MAPPING_CHART_mentions')
                        }
                    }
                }
            });
    
    • To setup config variables and render the text without pipes as it's not always a translated string
    this.config = {
                requiredList: true,
                bannedList: false,
                allowSpaces: false,
                allowComma: false,
                colorsType: false,
                defaultEnterAction: 'required',
                requiredTooltip: this.$translate.instant('D_CLIPPING_TAGS__REQUIRED_TOOLTIP'),
                bannedTooltip: this.$translate.instant('D_CLIPPING_TAGS__BANNED_TOOLTIP')
            };
    
    • To set window.title :) :
    SetWindowTitle(title:string) {
            if (!!title) {
                this.$window.document.title = this.$translate.instant(title);
            }
        }
    
    • Custom date formatting:
    dateHuman(date:Date):string {
            return date.getDate() + ' ' + this.$translate.instant('GLOBAL_CALENDAR_MONTH_' + date.getMonth())
                + ' ' + date.getFullYear();
        }
    
    • Sort things based on translated values:
    // Sort types
                tmpTypes = _.sortBy(tmpTypes, (type:string):string => {
                    // 'MISC' at the end
                    if ('MISC' === type) {
                        return 'zzzzz';
                    }
    
                    return this.$translate.instant('FACET_phrases2__TYPE_' + type);
                });
    
    GetSortedLanguages():IFacetLangDetectedCommonServiceLanguageObject[] {
            // We have to sort by translated languages!
            return _.sortBy(_.map(this.facetOptions, (item:string):any => {
                return {
                    key: item,
                    label: this.$translate.instant('FACET_langDetected_' + item),
                    cssStyle: (_.includes(['english', 'catalan', 'spanish', 'french', 'italian'], item))
                        ? {'font-weight': 'bold'} : null,
                    flag: _.get(this.lutFlags, item, null)
                };
            }), (item):string => {
                return item.label.toLowerCase();
            });
        }
    
    • Export raw data to CSV or Excel with translated values:
    getDataExportStacked(inputData:any):any {
            let exportData = angular.copy(inputData);
    
            if (angular.isArray(exportData) && exportData.length) {
                exportData[0].name = this.$translate.instant('CLIPPINGS__CHARTS_volume_TITLE');
    
                exportData[0].data = _.map(exportData[0].data, (inputDataItem:any):any => {
                    return {
                        'label': inputDataItem.association.profileName,
                        'value': inputDataItem.value
                    };
                });
            }
    
            return exportData;
        }
    
    • Set config strings to third party plugins:
    UpdateCalendarStrings():void {
            Highcharts.setOptions({
                lang: {
                    months: [
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_January'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_February'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_March'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_April'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_May'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_June'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_July'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_August'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_September'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_October'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_November'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_December')
                    ],
                    shortMonths: [
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jan'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Feb'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Mar'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Apr'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_May'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jun'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Jul'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Aug'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Sep'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Oct'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Nov'),
                        this.$translate.instant('GLOBAL_CALENDAR_MONTH_SHORT_Dec')
                    ],
                    weekdays: [
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Sunday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Monday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Tuesday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Wednesday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Thursday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Friday'),
                        this.$translate.instant('GLOBAL_CALENDAR_DAY_Saturday')
                    ]
                }
            });
        }
    
    **What is the motivation / use case for changing the behavior?** Be able to translate strings outside templates.

    Please tell us about your environment:

    • Angular version: 2.0.0-rc.6
    • Browser: [all]
    • Language: [TypeScript 2.0.2 | ES5 | SystemJS]

    @vicb

    feature area: i18n freq3: high 
    opened by marcalj 204
  • ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked on ng 4

    ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked on ng 4

    I'm submitting a ...

    
    [ ] Regression (behavior that used to work and stopped working in a new release)
    [X ] Bug report #14748 
    [ ] Feature request
    [ ] Documentation issue or request
    [ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
    

    Current behavior

    After using an observable object in my template using async, I am receiving : ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: ''. Current value: 'something'

    Expected behavior

    Please tell us about your environment

    
    Angular version: 4.2.2
    
    Browser:
    - [X] Chrome (desktop) version Version 58.0.3029.110 (64-bit)
     
    For Tooling issues:
    - Node version: v6.10.3
    - Platform: Mac
    
    		                                  
    		                                    type: bug/fix regression area: core 
    	                                    
    opened by altreze 201
  • Dynamically load template for a component

    Dynamically load template for a component

    I'm submitting a [X] feature request

    I have a component which provides some generic business logic. Let's say:

    • CRUD functionality
    • Productmanagement (product catalogue)
    • Cross department business management (separate layout for each department)
    • ...

    Depending on a condition I want to show a layout (template) which is specific for a type of product, related to the user department, etc. Right now I can't load a template on the fly for doing this. I have read through all the issues here and on stackoverflow for possible ways on doing this.

    The most practicabel way is the ngTemplateLayout. But in real life if you have dozens of different layout types, it blows up your template file and make unmaintenable.

    If you use the dynamiccomponentloader which is the most recommend way by the angular team, it adds an huge overhead of code for generating the component dynamically, even if the functionality for component and module creation is encapsulated. In addition it doesn't allow a real generic solution, because in the ngModule which has also be created dynamically you have to provide all imports, exports, providers, ... to make the component work. So if you don't want to have a huge overhead in your generic component builder, you have to implement a generic componentbuilder for each "type" of your form types. Which is not practicable and increases the danger of recoding all after the next angular release

    Expected behavior Provide a way of loading a template dynamically for a component. As it is available in Angular 1 Please don't be dogmatic on this issue and consider supporting real world requirements in Angular 2 Thanks

    feature area: core feature: under consideration 
    opened by KarlXOL 200
  • Angular2 AOT compilation -

    Angular2 AOT compilation - "Cannot determine the module for class (... many components which are unused)"

    [ x ] bug report => search github for a similar issue or PR before submitting
    [ ] feature request
    [ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
    

    Current behavior Unused components/pipes/directives in my workspace are detected by the compiler, which throws the error Cannot determine the module for class (...) for each file. It stops compilation, and does not seem be configurable. This is a problem, since I need to have those files in my workspace, but do not need them in the resultant app (partner implementations requiring different combos of shared components). This is especially frustrating with regards to compiling in a webpack loader, which should be able to provide a list of files which are included, regardless of workspace.

    Expected behavior I would expect these errors to be warnings, and/or able to be silenced by a compiler option. Alternatively, with regards to webpack, you could allow a list of files to be inserted, so that a webpack could provide all files in the require chain, instead of all files in the workspace.

    Minimal reproduction of the problem with instructions Cannot demo in plunkr, since it uses JIT.

    1. Create a basic angular app which bootstraps an ngModule with one component, AppComponent
    2. Get this app into a state which can be AOT compiled (should be pretty easy with a hello world)
    3. Add a component to the directory structure, but do not reference it anywhere in your code.
    4. Try to AOT compile again. You will get the warning Cannot determine the module for class

    What is the motivation / use case for changing the behavior? My company has a base app for ourselves, and our partners use modified versions of that app as their own. Rather than maintain all partners separately, we use a shared library of common generic components, imported as needed. For our base app, everything is fine, since we use every component. For partners, we cannot use AOT, since some of the components in the shared npm package do not have a declared module.

    Please tell us about your environment: Happens across all devices, but the current testing setup is: WIndows 10 VS Code Cmder (bash terminal)

    • Angular version: v2.1.0 (though we have also tested in 2.3.1

    • Browser: All - this is a compiler issue, not browser specific

    • Language: Typescript

    • Node (for AoT issues): node v6.3.0

    hotlist: error messages freq1: low area: compiler core: NgModule type: confusing P5 
    opened by swimmadude66 185
  • Reactive forms are not strongly typed

    Reactive forms are not strongly typed

    [x] feature request
    
    • Angular version: 2

    Reactive forms is meant to be used in complex forms but control's valueChanges are Observable<any>, which are totally against good practices for complex code.

    There should be a way to create strongly typed form controls.

    feature state: WIP effort3: weeks workaround3: complex freq3: high area: forms forms: validators forms: Controls API cross-cutting: types design complexity: major forms: ControlValueAccessor risky feature: under consideration 
    opened by asfernandes 152
  • Proposal: Need ability to add directives to host elements in component declaration.

    Proposal: Need ability to add directives to host elements in component declaration.

    I've been digging into Angular 2 and have run into a potential road block for extending certain kinds of components.

    In the the following example, I have a button component, and a directive that will apply styles based on touch events. There will be many other objects other than just the button that will inherit the exact same touch behavior. I've explored my options, and I'm at a loss:

    • Directly extend a TouchClass. This seems less than ideal since typescript doesn't support multiple class inheritance, and I'd also like to expose the behavior to consumers for use in their own classes.
    • Fake multiple class inheritance through an interface. This seems like a hack and requires me to redeclare a shim api on every class I'm trying to mix into. https://www.stevefenton.co.uk/2014/02/TypeScript-Mixins-Part-One/
    • Create a helper function that does it through a service directly on elementRef.nativeElement in the component constructor. I really don't want to do this since it states in the docs that nativeElement will be null when running in a worker, and that capability is something I'm the most excited about.

    Without getting too deep into the guts, I'd presume that the componentMetadata is available during the components compile time, and that the host property could be scanned for additional directives that could be added dynamically and compiled at the same time. This would allow you to do mixins the angular way: using composable directives to extend functionality, and doing it without breaking view projection. Short example below.

    Current behavior Declaring a directive in componentMetadata.host treats it as a regular attribute

    Expected/desired behavior The directive declared in host would be processed at compile time.

    /**
     * App
     */
    @Component({
        selector: 'app-component',
        template: '<g-btn>TEST</g-btn>',
        directives: [gBtn, gTouch]
    })
    
    export class AppComponent {
        constructor() {
    
        }
    }
    
    /**
     * Touch Directive
     * Will be used in lots and lots of components
     */
    @Directive({
        selector: '[g-touch]',
        host: { 
            '(touchstart)': '...',
            '(touchend)': '...',
            '(touchmove)': '...',
            '(touchcancel)': '...'
        }
    })
    
    export class gTouch {
        constructor() {
    
        }
    }
    
    /**
     * Simple button component
     */
    @Component({
        selector: 'g-btn',
        template: '<ng-content></ng-content>',
        host: {
            'role': 'button',
            // WOULD LOVE FOR THIS TO COMPILE THE DIRECTIVE!
            // right now it just adds an attribute called g-touch
            'g-touch': ' ' 
        }
    })
    
    export class gBtn {
    
        constructor() {
    
        }
    }
    

    Some ideas of how this could work:

    // Option 1: just scan the host properties for directives.
    // This would be my ideal, simple and understandable
    @Component({
        selector: 'g-btn',
        template: '<ng-content></ng-content>',
        host: {
            'role': 'button',
            'g-touch': true // or {prop: 'foo'} or string
        }
    })
    
    // Option 2: definitely more declarative using a hostDirectives property
    // more declarative, albeit more annoying to have to reimport the touch class
    @Component({
        selector: 'g-btn',
        template: '<ng-content></ng-content>',
        hostDirectives: gTouch,
        host: {
            'role': 'button',
            'g-touch': true
        }
    })
    
    // Option 3: declare host directives as its own thing, still just
    // use keys pointing to bool, obj, or string
    @Component({
        selector: 'g-btn',
        template: '<ng-content></ng-content>',
        hostDirectives: {
            'g-touch': {someOption: someOption}
        },
        host: {
            'role': 'button',
        }
    });
    
    // Option 4: Not a huge fan of this one, but understandable if
    // people want to keep one host property
    @Component({
        selector: 'g-btn',
        template: '<ng-content></ng-content>',
        host: {
            'role': 'button',
            _directives: {
                'g-touch': true
            }
        }
    });
    

    Thanks everyone, Angular 2 is looking great!. Let me know if theres something I'm missing.

    feature area: core state: has PR core: directive matching core: host and host bindings feature: under consideration 
    opened by jamesmfriedman 145
  • NgModule on Large Projects

    NgModule on Large Projects

    I'm submitting a ... (check one with "x")

    [X] feature request / proposal
    

    I've been reading about NgModule and I want to lay out some use cases that I'm not entirely sure the current proposal (https://docs.google.com/document/d/1isijHlib4fnukj-UxX5X1eWdUar6UkiGKPDFlOuNy1U/pub) takes into consideration.

    Context

    I'm part of a team building an Enterprise Framework (based on Angular 2). This framework will then be the base for other apps within the same ecosystem.

    We have divided the framework into smaller projects/modules (think of them as separated npm packages). These modules are sets of controls (that are then reused across other modules) or pages that use those controls.

    Example

    A quick example can be:

    Controls Module

    import {Component} from "@angular/core";
    
    @Component({
       selector: "my-combobox",
       ...
    })
    export class MyComboBox{
    
    }
    

    Checklist Module // Checklist module depends on Controls module. Controls is treated as a 3rd party module.

    import {Component} from "@angular/core";
    import {MyComboBox} from "controlsmodule/components/mycombobox";
    // Please note that we are only loading a specific component within the module, not all components inside that module.
    
    @Component({
         selector: "my-checklist-page",
         directives: [MyComboBox, ...],
         ...
    })
    export class ChecklistPage{
    
    }
    

    Bootstrap doesn't know both Controls and Checklist modules. They are lazy loaded depending user's interaction. In this case, if the user navigates to a Checklist, the ChecklistPage component will be loaded and then the MyComboBox will also follow (because of the import made by ChecklistPage)

    Checklist module has other dozen components. Each depending on other dozen components from multiple modules.

    It's impractical (not to say nearly impossible) to have all components imported into the NgModule declaration. We are talking of several hundreds of components that might be used during app run time.

    Also, the application needs to be modular and lazy load when possible. Different interactions within the app will lead to completely different modules being loaded.

    Expected/desired behavior

    The current solution, with component scoped directives, works like a charm for this use case. Not sure how this will play out with NgModule.

    More than that, currently we can clearly see the dependencies needed by each component (in this case ChecklistPage). Making maintenance that much more easy.

    Having all needed components imported into a NgModule, and then using them indistinctly on several components seems a fantastic solution for small applications. I feel that on a long term development, with several iterations across multiple years, with team rotation, ... having each component explicitly state on what it depends without looking into the template (and having compilation errors when something is missing) is a great advantage.

    Conclusion

    Please let me know if I was clear in my explanation. The goal of this issue is to raise awareness about this situation and get feedback from you on how to proceed.

    We are available to show you our current work, we have several hundred Angular 2 components across 8 projects developed in the last year (since alpha 27).

    opened by jpsfs 144
  • Several fixes for universal example.

    Several fixes for universal example.

    fix(docs-infra): correctly read example type

    Prior to this change the universal example was broken as the example type was not retrieved correctly in bazel which caused the _renameFile method to be called with incorrect context.

    Closes #48664


    docs: update universal example

    This change updates the universal example to align with latest CLI changes.

    area: docs action: review target: patch 
    opened by alan-agius4 0
  • fix(language-service): update packages/language-service/build.sh script to work with vscode-ng-language-service's new Bazel build

    fix(language-service): update packages/language-service/build.sh script to work with vscode-ng-language-service's new Bazel build

    2nd half of https://github.com/angular/vscode-ng-language-service/pull/1846. npm_traslate_lock in vscode-ng-language-service now has a data attribute so sed should only add another item to the list instead of adding a duplicate data attribute.

    opened by gregmagolan 0
  • Get value of the validations applied to control. ie., minLegth or maxLength

    Get value of the validations applied to control. ie., minLegth or maxLength

    Which @angular/* package(s) are relevant/related to the feature request?

    forms

    Description

    I'm developing a UI to display the counter next to the input field to show the 10/100 character count against the maximum value allowed.

    I have set Validators.maxLength(100) validation but there is no option to get the maximum value set for the validator.

    One way to do this is to set the maximum value statically but I want to keep it dynamic against the validation set for the control.

    Proposed solution

    The list of validators applied on a control could be exposed with metadata containing the set values for each validation.

    This will be helpful in the runtime check for the validation value.

    Alternatives considered

    The validation and its value are exposed when an error occurs (validation fail) on the control. But this cannot be used in the counter because the value will be disclosed only when there is an error.

    opened by anuj-scanova 1
  • Error: Cannot find module '/c/users/suraj/_bazel~1/k7jdsxj6/execroot/angular/bazel-

    Error: Cannot find module '/c/users/suraj/_bazel~1/k7jdsxj6/execroot/angular/bazel-

    Which @angular/* package(s) are the source of the bug?

    bazel, core

    Is this a regression?

    Yes

    Description

    After running the cmd : yarn bazel run //packages/examples/core:devserver

    getting the error:

    node:internal/modules/cjs/loader:936 throw err; ^

    Error: Cannot find module '/c/users/suraj/_bazel~1/k7jdsxj6/execroot/angular/bazel-~1/x64_wi~1/bin/packages/examples/core/devser~2.run/angular/c:\users\suraj_bazel_suraj\k7jdsxj6\execroot\angular\bazel-out\x64_windows-fastbuild\bin\packages\examples\core\devserver.exe.runfiles/build_bazel_rules_nodejs/internal/node/node_patches.cjs' Require stack:

    • internal/preload at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.Module._load (node:internal/modules/cjs/loader:778:27) at Module.require (node:internal/modules/cjs/loader:1005:19) at Module._preloadModules (node:internal/modules/cjs/loader:1276:12) at loadPreloadModules (node:internal/bootstrap/pre_execution:484:5) at prepareMainThreadExecution (node:internal/bootstrap/pre_execution:78:3) at node:internal/main/run_main_module:7:1 { code: 'MODULE_NOT_FOUND', requireStack: [ 'internal/preload' ] } error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

    Please provide a link to a minimal reproduction of the bug

    No response

    Please provide the exception or error you saw

    node:internal/modules/cjs/loader:936
      throw err;
      ^
    
    Error: Cannot find module '/c/users/suraj/_bazel~1/k7jdsxj6/execroot/angular/bazel-~1/x64_wi~1/bin/packages/examples/core/devser~2.run/angular/c:\users\suraj\_bazel_suraj\k7jdsxj6\execroot\angular\bazel-out\x64_windows-fastbuild\bin\packages\examples\core\devserver.exe.runfiles/build_bazel_rules_nodejs/internal/node/node_patches.cjs'
    Require stack:
    - internal/preload
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
        at Function.Module._load (node:internal/modules/cjs/loader:778:27)
        at Module.require (node:internal/modules/cjs/loader:1005:19)
        at Module._preloadModules (node:internal/modules/cjs/loader:1276:12)
        at loadPreloadModules (node:internal/bootstrap/pre_execution:484:5)
        at prepareMainThreadExecution (node:internal/bootstrap/pre_execution:78:3)
        at node:internal/main/run_main_module:7:1 {
      code: 'MODULE_NOT_FOUND',
      requireStack: [ 'internal/preload' ]
    }
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
    

    Please provide the environment you discovered this bug in (run ng version)

    Angular CLI: 15.0.4
    Node: 16.19.0
    Package Manager: npm 7.21.1
    OS: win32 x64
    

    Anything else?

    No response

    opened by surajy93 0
  • build: update dependency jsdom to v21

    build: update dependency jsdom to v21

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | jsdom | devDependencies | major | ^20.0.0 -> ^21.0.0 |


    Release Notes

    jsdom/jsdom

    v21.0.0

    Compare Source

    A potentially-breaking bug fix:

    • Fixed the window, document, location, and top properties of Window to be non-configurable. (ExE-Boss)

    Other changes:

    • Added support for <input type=image> submitting forms. (jenseng)
    • Added the location setter to the Window object, which forwards to the location.href setter. Setting the URL is still only implemented for fragment navigations, however. (ExE-Boss)
    • Fixed defer="" <script> elements that are added after DOMContentLoaded to execute, instead of being skipped.
    • Fixed selectElement.selectedOptions being incorrect when optionElement.selected is set. This was a regression introduced in v20.0.1. Unfortunately this also reverts the performance improvement when appending <option> elements that was introduced then. (eps1lon)
    • Fixed the self, locationbar, menubar, personalbar, scrollbars, statusbar, toolbar, frames, parent, external, length, and screen properties of Window to be replaceable: that is, setting them will override their values, instead of having the new value be ignored. (ExE-Boss)
    • Fixed a few issues with JSOM.fromURL() in the browser build of jsdom. (LungZeno)

    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by Renovate Bot.

    area: build & ci action: review target: patch 
    opened by angular-robot 0
  • feat(compiler-cli): add extended diagnostics to check for component v…

    feat(compiler-cli): add extended diagnostics to check for component v…

    …ariable shadowing template reference

    for example

    @COMPONENT({
      template: '<div #var1></div>'
    })
    export class FooComponent {
      var1: string;
    }
    

    fixes #45227

    right now this goes without error, but it can lead to mistakenly inside the template to use the template reference as if it was the component variable

    PR Checklist

    Please check if your PR fulfills the following requirements:

    • [x] The commit message follows our guidelines: https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
    • [x] Tests for the changes have been added (for bug fixes / features)
    • [ ] Docs have been added / updated (for bug fixes / features)

    PR Type

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [x] Feature
    • [ ] Code style update (formatting, local variables)
    • [ ] Refactoring (no functional changes, no api changes)
    • [ ] Build related changes
    • [ ] CI related changes
    • [ ] Documentation content changes
    • [ ] angular.io application / infrastructure changes
    • [ ] Other... Please describe:

    What is the current behavior?

    Issue Number: 45227

    What is the new behavior?

    it will show warning when there is shadowing between component variable and template reference

    Does this PR introduce a breaking change?

    • [ ] Yes
    • [ ] No

    I guess it's not, because it's a warning not an error, but I'm leaving it for the Angular team to decide

    to fix the warning, simply rename the component variable or the template reference

    Other information

    this will show the warning even if the component variable is private, which in my opinion is correct but in case the Angular team disagree, I will make it only show the warning in case of protect or public variables only

    detected: feature 
    opened by robertIsaac 0
Releases(15.1.0-rc.0)
  • 15.1.0-rc.0(Jan 5, 2023)

    15.1.0-rc.0 (2023-01-05)

    common

    | Commit | Description | | -- | -- | | fix - 2f4f0638c7 | Add data attribtue to NgOptimizedImage (#48497) |

    compiler

    | Commit | Description | | -- | -- | | feat - a532d71975 | allow self-closing tags on custom elements (#48535) | | fix - 33f35b04ef | type-only symbols incorrectly retained when downlevelling custom decorators (#48638) |

    compiler-cli

    | Commit | Description | | -- | -- | | fix - caedef0f5b | update @babel/core dependency and lock version (#48634) |

    localize

    | Commit | Description | | -- | -- | | fix - a1a8e91eca | add triple slash type reference on @angular/localize on `ng add (#48502) |

    migrations

    | Commit | Description | | -- | -- | | fix - cc284afbbc | combine newly-added imports in import manager (#48620) |

    Special Thanks

    Alan Agius, Alex Castle, Andrew Kushnir, Derek Cormier, Joey Perrott, Kristiyan Kostadinov, Matthieu Riegler, Paul Gschwendtner, Pawel Kozlowski, Renan Ferro, Vadim, ced, mgechev, piyush132000 and robertIsaac

    Source code(tar.gz)
    Source code(zip)
  • 15.1.0-next.3(Dec 14, 2022)

    15.1.0-next.3 (2022-12-14)

    animations

    | Commit | Description | | -- | -- | | fix - c86484507f | fix incorrect handling of camel-case css properties (#48436) |

    common

    | Commit | Description | | -- | -- | | feat - fe50813664 | Add BrowserPlatformLocation to the public API (#48488) | | fix - e362214924 | Fix TestBed.overrideProvider type to include multi (#48424) | | fix - d87285c363 | Update Location to get a normalized URL valid in case a represented URL starts with the substring equals APP_BASE_HREF (#48394) |

    compiler-cli

    | Commit | Description | | -- | -- | | fix - a6849f27af | evaluate const tuple types statically (#48091) |

    router

    | Commit | Description | | -- | -- | | feat - f58ad86e51 | Add feature provider for enabling hash navigation (#48301) |

    Special Thanks

    Alan Agius, Andrew Kushnir, Andrew Scott, Aristeidis Bampakos, Bob Watson, BrowserPerson, Jens, Jessica Janiuk, Joey Perrott, JoostK, Konstantin Kharitonov, Lukas Matta, Matthieu Riegler, Piotr Kowalski, Virginia Dooley, Yannick Baron, dario-piotrowicz, lsst25, piyush132000 and why520crazy

    Source code(tar.gz)
    Source code(zip)
  • 15.0.4(Dec 14, 2022)

    15.0.4 (2022-12-14)

    animations

    | Commit | Description | | -- | -- | | fix - 6c1064c72f | fix incorrect handling of camel-case css properties (#48436) |

    common

    | Commit | Description | | -- | -- | | fix - f30d18a942 | Fix TestBed.overrideProvider type to include multi (#48424) | | fix - 59c6bfb632 | Update Location to get a normalized URL valid in case a represented URL starts with the substring equals APP_BASE_HREF (#48394) |

    compiler-cli

    | Commit | Description | | -- | -- | | fix - b55d2dab5d | evaluate const tuple types statically (#48091) |

    Special Thanks

    Alan Agius, Andrew Kushnir, Andrew Scott, Aristeidis Bampakos, Bob Watson, BrowserPerson, Jens, Jessica Janiuk, Joey Perrott, JoostK, Konstantin Kharitonov, Lukas Matta, Piotr Kowalski, Virginia Dooley, Yannick Baron, dario-piotrowicz, lsst25, piyush132000 and why520crazy

    Source code(tar.gz)
    Source code(zip)
  • 15.1.0-next.2(Dec 7, 2022)

    15.1.0-next.2 (2022-12-07)

    common

    | Commit | Description | | -- | -- | | fix - 8e52ca2714 | Don't generate srcsets with very large sources (#47997) | | fix - f8ecc194e9 | Update Location to support base href containing origin (#48327) |

    compiler

    | Commit | Description | | -- | -- | | fix - 4c023956d8 | make sure selectors inside container queries are correctly scoped (#48353) |

    compiler-cli

    | Commit | Description | | -- | -- | | fix - 27eaded62d | Produce diagnostic rather than crash when using invalid hostDirective (#48314) |

    core

    | Commit | Description | | -- | -- | | feat - 38421578a2 | Make the isStandalone() function available in public API (#48114) | | feat - dd42974b07 | support TypeScript 4.9 (#48005) | | fix - 5f9c7ceb90 | unable to inject ChangeDetectorRef inside host directives (#48355) |

    Special Thanks

    Alan Agius, Alex Castle, Andrew Kushnir, Andrew Scott, Bob Watson, Charles Lyding, Derek Cormier, Joey Perrott, Konstantin Kharitonov, Kristiyan Kostadinov, Matthieu Riegler, Paul Gschwendtner, Pawel Kozlowski, dario-piotrowicz, piyush132000 and sr5434

    Source code(tar.gz)
    Source code(zip)
  • 15.0.3(Dec 7, 2022)

    15.0.3 (2022-12-07)

    common

    | Commit | Description | | -- | -- | | fix - 50b1c2bf52 | Don't generate srcsets with very large sources (#47997) | | fix - bf44dc234a | Update Location to support base href containing origin (#48327) |

    compiler

    | Commit | Description | | -- | -- | | fix - 9a5d84249a | make sure selectors inside container queries are correctly scoped (#48353) |

    compiler-cli

    | Commit | Description | | -- | -- | | fix - 167bc0d163 | Produce diagnostic rather than crash when using invalid hostDirective (#48314) |

    core

    | Commit | Description | | -- | -- | | fix - e4dcaa513e | unable to inject ChangeDetectorRef inside host directives (#48355) |

    Special Thanks

    Alan Agius, Alex Castle, Andrew Kushnir, Andrew Scott, Bob Watson, Derek Cormier, Joey Perrott, Konstantin Kharitonov, Kristiyan Kostadinov, Paul Gschwendtner, Pawel Kozlowski, dario-piotrowicz and piyush132000

    Source code(tar.gz)
    Source code(zip)
  • 15.1.0-next.1(Nov 30, 2022)

    15.1.0-next.1 (2022-11-30)

    Deprecations

    router

    • CanLoad guards in the Router are deprecated. Use CanMatch instead.

    compiler-cli

    | Commit | Description | | -- | -- | | fix - 7d88700933 | accept inheriting the constructor from a class in a library (#48156) |

    router

    | Commit | Description | | -- | -- | | docs - 228e992db7 | Deprecate canLoad guards in favor of canMatch (#48180) | | feat - 332461bd0c | Add ability to override onSameUrlNavigation default per-navigation (#48050) |

    Special Thanks

    Alan Agius, Andrew Scott, Aristeidis Bampakos, Bob Watson, Derek Cormier, Dylan Hunn, JoostK, Kristiyan Kostadinov, Matthieu Riegler, Paul Gschwendtner, Pawel Kozlowski, Rokas Brazdžionis and piyush132000

    Source code(tar.gz)
    Source code(zip)
  • 15.0.2(Nov 30, 2022)

    15.0.2 (2022-11-30)

    compiler-cli

    | Commit | Description | | -- | -- | | fix - 86a21f5569 | accept inheriting the constructor from a class in a library (#48156) |

    Special Thanks

    Alan Agius, Andrew Scott, Aristeidis Bampakos, Bob Watson, Derek Cormier, JoostK, Kristiyan Kostadinov, Matthieu Riegler, Paul Gschwendtner, Pawel Kozlowski, Rokas Brazdžionis, mgechev and piyush132000

    Source code(tar.gz)
    Source code(zip)
  • 15.1.0-next.0(Nov 23, 2022)

    15.1.0-next.0 (2022-11-22)

    Deprecations

    router

    • router writable properties

      The following strategies are meant to be configured by registering the application strategy in DI via the providers in the root NgModule or bootstrapApplication:

      • routeReuseStrategy
      • titleStrategy
      • urlHandlingStrategy

      The following options are meant to be configured using the options available in RouterModule.forRoot or provideRouter.

      • onSameUrlNavigation
      • paramsInheritanceStrategy
      • urlUpdateStrategy
      • canceledNavigationResolution

      The following options are available in RouterModule.forRoot but not available in provideRouter:

      • malformedUriErrorHandler - This was found to not be used anywhere internally.
      • errorHandler - Developers can instead subscribe to Router.events and filter for NavigationError.

    common

    | Commit | Description | | -- | -- | | fix - b0a62bea47 | Fix MockPlatformLocation events and missing onPopState implementation (#48113) |

    core

    | Commit | Description | | -- | -- | | feat - 6acae1477a | Add TestBed.runInInjectionContext to help test functions which use inject (#47955) |

    forms

    | Commit | Description | | -- | -- | | fix - 0329c13e95 | don't mutate validators array (#47830) | | fix - d321880440 | FormBuilder.group return right type with shorthand parameters. (#48084) |

    language-service

    | Commit | Description | | -- | -- | | feat - 5f0b53c735 | Allow auto-imports to suggest multiple possible imports. (#47787) | | fix - fd2eea5961 | correctly handle host directive inputs/outputs (#48147) | | fix - ce8160ecb2 | Prevent crashes on unemitable references (#47938) | | fix - 764fa3d9c3 | update packages/language-service/build.sh script to work with vscode-ng-language-service's new Bazel build (#48120) |

    router

    | Commit | Description | | -- | -- | | docs - 0a8b8a66cd | Deprecate public members of Router that are meant to be configured elsewhere (#48006) | | feat - 73f03ad2d2 | Add new NavigationSkipped event for ignored navigations (#48024) | | fix - b51929a394 | correct type of nextState parameter in canDeactivate (#48038) | | fix - 1df0ed7d6e | Ensure renavigating in component init works with enabledBlocking (#48063) | | fix - 1976e37475 | restore 'history.state' on popstate even if navigationId missing (#48033) |

    Special Thanks

    Alan Agius, Andrew Kushnir, Andrew Scott, Bjarki, Bob Watson, Brooke, Derek Cormier, Dylan Hunn, George Kalpakas, Greg Magolan, Ikko Ashimine, Ivan Rodriguez, Jessica Janiuk, JiaLiPassion, Joe Roxbury, Joey Perrott, Kristiyan Kostadinov, Matthieu Riegler, Mikhail Savchuk, Nebojsa Cvetkovic, Pawel Kozlowski, Volodymyr, Wooshaah and mgechev

    Source code(tar.gz)
    Source code(zip)
  • 15.0.1(Nov 23, 2022)

    15.0.1 (2022-11-22)

    common

    | Commit | Description | | -- | -- | | fix - 930af9dd26 | Fix MockPlatformLocation events and missing onPopState implementation (#48113) |

    forms

    | Commit | Description | | -- | -- | | fix - b342e55509 | don't mutate validators array (#47830) | | fix - a12a120272 | FormBuilder.group return right type with shorthand parameters. (#48084) |

    language-service

    | Commit | Description | | -- | -- | | fix - cc8b76ef7c | correctly handle host directive inputs/outputs (#48147) | | fix - a8c33bf931 | update packages/language-service/build.sh script to work with vscode-ng-language-service's new Bazel build (#48120) |

    router

    | Commit | Description | | -- | -- | | fix - e4309d57d8 | correct type of nextState parameter in canDeactivate (#48038) | | fix - 9baefd085f | Ensure renavigating in component init works with enabledBlocking (#48063) | | fix - fa5528fb5f | restore 'history.state' on popstate even if navigationId missing (#48033) |

    Special Thanks

    Alan Agius, Andrew Scott, Bjarki, Bob Watson, Brooke, Derek Cormier, Dylan Hunn, George Kalpakas, Greg Magolan, Ikko Ashimine, Ivan Rodriguez, Jessica Janiuk, Joe Roxbury, Joey Perrott, Kristiyan Kostadinov, Matthieu Riegler, Mikhail Savchuk, Nebojsa Cvetkovic, Pawel Kozlowski, Volodymyr and Wooshaah

    Source code(tar.gz)
    Source code(zip)
  • 12.2.17(Nov 22, 2022)

    12.2.17 (2022-11-22)

    Breaking Changes

    core

    • Existing iframe usages may have security-sensitive attributes applied as an attribute or property binding in a template or via host bindings in a directive. Such usages would require an update to ensure compliance with the new stricter rules around iframe bindings.

    core

    | Commit | Description | | -- | -- | | fix - b871db57da | hardening attribute and property binding rules for