4

So I’ve been playing around with angular and I learned about two-way binding using “ngModel”. I got this idea, but I can’t seem to implement it, would appreciate any help on this:

What I’m trying to do: So I will have an input field, that’ll take ticket prices for “Adult”, and a similar one for “Child”. I have another two input fields that’ll calculate the ticket prices based on the fixed rates. Then I want a third field where the sum of both their calculated prices is printed. I’ve tried this so far, but can't figure out what to do now. Any help would be greatly appreciated, thank you!

here’s the code:

<input type="text" [(ngModel)]="ticket.adult" name="adult">
<input type="text" value="{{ ticket.adult*15 }}">

<input type="text" [(ngModel)]="ticket.child" name="child">
<input type="text" value="{{ ticket.child*5 }}">


<p>Ticket Price:<!--the total price will be displayed here--></p>

P.S- I've declared a ticket object in its component.ts file.

5
  • An input field is used to gather... an input. The price is an output. Don't use an input field to display that output. Just use text. Regarding your question. You already know how to compute both prices. And you want to sum them. How do you add two numbers in JavaScript/TypeScript? Commented Jul 22, 2018 at 12:15
  • stackoverflow.com/questions/45348973/… check this out, may this help you Commented Jul 22, 2018 at 12:18
  • @JBNizet yeah I realize that, I just used the input field randomly. I know how to add two numbers in both, but the problem is how do I return it to a variable so it displays the sum. I've tried but it isn't working Commented Jul 22, 2018 at 12:23
  • Why do you think you need a variable? {{ ticket.child*5 + ticket.adult*15 }} is all you need. And if you don't like these multiplications being duplicated, then add methods in your component (or in the Ticket class), and call them in the view. Commented Jul 22, 2018 at 12:24
  • @JBNizet Thank you! I'll try and see if it works Commented Jul 22, 2018 at 12:31

2 Answers 2

2

Maybe this works:

get sum(): number {
  // calculate your price with your formula here, 
  return this.ticket.adult*15 + this.ticket.child*5;
}

And in your template:

<p>Ticket Price: {{sum}}</p>

In your .ts file, you can access the sum by just calling this.sum

DEMO: https://stackblitz.com/edit/angular-lmjyts?file=src/app/app.component.ts

Sign up to request clarification or add additional context in comments.

15 Comments

This will not return the total, also it should be {{sum()}} , controller ?
@Sajeetharan ever heard of get set in typescript? {{sum}} is the correct syntax.
sum is not a variable, here it is a function , as you say i am not an expert
Yes, you are talking about the syntax. I quote: it should be {{sum()}}.
btw i am not downvoting you
|
1

As JBNizet said, for semantic and possibly functional reasons you should avoid using <input> for displaying output. Thus you can rewrite your code like this:

<input type="text" [(ngModel)]="ticket.adult" name="adult">
<p>{{ ticket.adult*15 }}</p>

<input type="text" [(ngModel)]="ticket.child" name="child">
<p>{{ ticket.child*5 }}</p>


<p>Ticket Price: {{ ticket.adult * 15 + ticket.child * 5 }}</p>

However, you probably want to avoid rewriting your adult / child multipliers more than once simply to avoid duplication and also in case they change. My recommended solution in this case would be to use pipes since your calculation is deterministic.

@Pipe({ name: 'price' })
export class PricePipe implements PipeTransform {
  transform(amount, type) {
    let multiplier = 0; // perhaps throw an error or set a sane default
    switch (type) {
      case 'adult':
        multiplier = 15;
      case 'child':
        multiplier = 5;
    }

    return amount * multiplier;
  }
}

Now you could use it like:

<input type="text" [(ngModel)]="ticket.adult" name="adult">
<p>{{ ticket.adult | price:'adult' }}</p>

<input type="text" [(ngModel)]="ticket.child" name="child">
<p>{{ ticket.child | price:'child' }}</p>


<p>Ticket Price: {{ (ticket.adult | price:'adult') + (ticket.child | price:'child') }}</p>

Now you can keep the multipliers in one spot and even add other kinds of multipliers later on if you need to. You could even possibly refactor your code to iterate over 'adult' and 'child' properties to display the prices rather than hard coding the .adult and .child values.

7 Comments

What if we want to access the sum in the ts code?
You can inject pipes too
Yeah, I know, I mean this approach works but too cumbersome.
What is cumbersome about it?
1. You have to create the pipe, it takes some time. 2. Then in the ts code you need to inject it and call the pipe, not quite elegant to me.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.