How can I adhere to Angular 2's naming convention for Input and Output as suggested by the styleguide?

Working with inputs and outputs while following Angular 2's styleguide naming convention

Initially, my directive was defined like this:

...
inputs: [
'onOutside'
]
... 

export class ClickOutsideDirective {
@Output() onOutside: EventEmitter<any> = new EventEmitter();
}

However, the styleguide recommends not using the prefix on for outputs, as Angular 2 supports the on- syntax in templates.

Attempting to adjust it to:

@Input() outsideClick: any;
@Output() outsideClick: EventEmitter<any> = new EventEmitter();

But struggling to differentiate between the @Input and Output names without the on prefix.

In the previous approach, naming both the @Input and @Output the same worked, but errors occur when declared within the exported class.

Renaming @Input to outside and @Output to outsideClick seems counterintuitive since they represent the same function. outside is the action triggered by outsideClick.

Furthermore, if outside and outsideClick are no longer named identically, outsideClick may not know which function to execute.

How can I effectively name the @Input and @Output variables so that functionality is maintained while making sense, similar to the original example?

EDIT:

Example of how to use:

<div clickOutside [exceptions]="['.toggler']" (outside)="doSomethingOnOutsideClick()"></div> 

Answer №1

Avoid using the on prefix in JavaScript events; only event handlers should start with on. There is no onClick event in JS - instead, use the click event and assign a function to onClick for it to be called upon receiving the click event.

It's beneficial to name corresponding inputs and outputs when they are related.

@Input() name:any; 
@Output() nameChange: EventEmitter<any> = new EventEmitter();;

This enables Angular2's "two-way binding" shorthand.

[(name)]="someProp"

If you utilize @Input() and @Output() (the preferred method), there is no need for both inputs: [] and outputs: [] as they serve the same purpose, rendering one redundant.

To conform to the browser naming convention, consider:

(nameChange)="onNameChange($event)"

This allows an event handler named onNameChange to be triggered upon receiving the nameChange event.

If the event is not tied to an input/output pair, it may be best to omit the Change part.

(loggedIn)="onLoggedIn($event)

Answer №2

Indeed, the original poster posed multiple inquiries within a common framework, leading to distinct sections below.

Utilization and/or description

To enable support for Angular-2 and subsequent versions' "two-way binding", associate input with an output suffixed with Change, as shown:

@Input() password: string;
@Output() passwordChange: EventEmitter<string> = new EventEmitter();

This facilitates shorthand operation such as:

<app-my-component
    [(password)]="myPasswordProp"
    >
</app-my-component>

In the above example, I provide a default value to the component as input, while capturing user changes as output, essentially synchronizing myPasswordProp with MyComponent's internal state.

Nomenclature convention

In Angular-2 and later versions, reserve the "on" prefix exclusively for event handlers, not event emitters.

Note that using the "on" prefix for events is prohibited (and could result in compilation errors, particularly in newer Angular releases).

Even in JavaScript, there is no event named onClick; rather, it is referred to as click. The distinction lies in JS utilizing onClick as the attribute name where we assign event handlers, while Angular disallows this prefix.

Angular does permit the use of on for event handlers, like so:

(passwordChange)="onPasswordChange($event)"

Here, the onPasswordChange labeled event handler triggers upon activation of the passwordChange event.

However, if the event is not part of an input/output pair, skip the Change suffix when defining the output, opting instead for usage similar to:

(loggedIn)="onLoggedIn($event)"

Moreover, to adhere to browser-like naming conventions or differentiate events from other elements, our company adopted the "by" prefix, including examples like:

(byLogin)="onLogin($event)"

(bySave)="onSave($event)"

This method enhances readability, as it can be incorporated into human sentences, for instance:

  • "Our App's handler awaits action on login, spurred by login events originating from the library."

Conversely:

  • "The library's by login events trigger our App's handler, awaiting activity on login to transpire."

Readability serves as one rationale behind the utilization of both the "on" and "by" prefixes as implemented.

Class-based annotation vs Property-based annotation

Just as the initial post touched on this topic:

  • Employing @Input() and/or @Output() annotations with member variables stands as the preferred practice.

  • If you opt for the aforementioned approach, omit passing inputs: [] and/or outputs: [] to the class's annotation.

  • In essence, these two methods achieve analogous outcomes; employing one renders the other superfluous.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to create a transparent colored foreground in HTML?

Looking to create a translucent foreground color on a webpage? I'm aiming to give a hint of red to the overall look of the website. Edit: Just to clarify, I am not referring to changing font colors. I want a color that can overlay the entire page wit ...

Class does not have the capability to deserialize an array

I encountered this issue with my code (see image): Here is the snippet of my code: function CheckLoginData() { var user = []; user.Email = $("#tbEmail").val(); user.Password = $("#tbPassword").val(); $.ajax({ type: "POST", contentType: "applic ...

Determining Cost Using Quantity and Option Changes in Angular 4

Task In the shopping cart, there is a list of items with options, quantities, and prices. The goal is to calculate the total price based on any changes in the quantity and option of an item. Investigation I included [(ngModel)] for 2-way data binding, ...

implementing the reuse of form control names for multiple dropdowns in an Angular application

When using the dropdown menu, I am facing an issue where selecting a value from the second dropdown makes it disappear. This is because both dropdowns are using the same formControlName to pass values to the backend with the same header. How can this be fi ...

Separate each item in the list and display them across multiple pages within a table

I'm looking to display a list of 37 items across four separate pages within a table. Can anyone suggest a way to split these items and showcase them in four different pages using either javascript or vue.js? ...

Mastering the Art of Writing an Ajax Post Request

I am attempting to transmit an image URL to a node.js server from some JavaScript using the Ajax POST method. My expectation is for the server to respond with some text, but I'm encountering issues and unsure where the problem lies. Below is the relev ...

Creating unique ID tags using AngularJS

I am struggling with creating an HTML structure that looks like this: <ul> <li id="r1_1">Root node 1 <ul> <li id="child_node_1">Child node 1</li> <li id="child_node_2">Child node 2</ ...

The issue with the jQuery click event arises when utilizing the "Module Pattern"

Exploring the Module Pattern as described by Chris Coyyer here, I, an intermediate front-end JS developer, have encountered a problem. Specifically, when attempting to utilize a jQuery selector stored in the settings object, I am unable to trigger a click ...

What are the steps to start a ExpressJS server for webpages that are not index.html?

I am exploring how to browse/run/view web pages other than just the index.html file in my public folder, which contains multiple HTML files. I am using ExpressJS and NodeJS for this purpose, but every time I start my server, I can only access the index.htm ...

Angular 2: Testing Firebase Add Functionality with Unit Tests

Is there a way to perform a basic unit test in Angular 2 for testing a simple firebase adding item feature? I've opted for typescript over standard JavaScript in my code. This is the piece of code I want to test: export class AppComponent { r ...

Is it advisable to optimize your SEO by placing the JavaScript code at the bottom of your webpage?

Is this just an urban legend or is it actually true? I've heard that when web crawlers analyze a webpage, they have a time limit to capture all available code (like html) before moving on to the next page. If the JavaScript code is in the head sectio ...

"Can you share a method to extract the value from a TextField component in a React hook-based Material-

Currently, I am using Material-UI within a React project and have a component set up like this: const UserDetail = (props: ListDetailProps) => { const oldpassword = useRef<TextFieldProps>(null); const newpassword = useRef<TextFieldProps ...

Switch from using jQuery to vanilla JavaScript for handling POST requests

I am looking to eliminate the jQuery dependency and use plain JavaScript instead in the code below for a post request. <script type="text/javascript> $(function() { $.post("test_post.php", { name: "John Doe", ...

Adjust the HTML content prior to displaying it to prevent any flickering

Is there a way to run code before the page is rendered, such as updating dates or converting text to HTML, without causing flickering when reloading multiple times? How can I ensure the code runs as it's drawn instead of waiting until the end to redra ...

Having issues with Angular chart.js onClick event? Learn how to retrieve all elements of a bar when it is clicked on

As a newcomer to Chart.js, I am exploring how to implement click events for when a chart is generated. My current challenge involves accessing all the elements of a bar upon clicking it. Unfortunately, the onClick method is not functioning as expected at ...

The issue with the left border color not functioning in JavaScript

Attempting to alter the border-left-color property using this script is resulting in a Uncaught SyntaxError: Unexpected token -. Is border-left-color actually supported? Javascript function logoChange() { var description = new Array (); description[0] ...

How can I detect Mongoose events through syntax?

Is there a way to detect the open event in Mongoose based on their documentation located here? According to the documentation, once connected, the open event is fired on the Connection instance. If you're using mongoose.connect, the Connection is m ...

Embed a div element within a content-editable area

Is there a way to add a div with text to a contenteditable element and automatically select the text between the div tags after inserting the div? div.innerHTML +='<div id="id">selecttext</div>' I have tried this method, but it does ...

Utilizing the power of JavaScript within HTML to remove elements upon being clicked

Seeking help again for the page I'm building where I keep encountering errors. As a beginner, I find myself puzzled and in need of assistance. My task is to utilize a for loop to iterate over the images and attach an event listener to each one so that ...

Encountering an issue with eslint-loader in a new VueJS project: TypeError - eslint.CLIEngine is not recognized as

Embarking on a fresh VueJS venture with WebStorm. A brand new VueJS project has been established, NPM upgraded, Vuetify added, and upon server initiation, an error pops up: ERROR Failed to compile with 1 errors ...