why doesn't toFixed() work in my React functional component? - javascript

I have a number passed down in props to a functional component, and in it, I'm trying to make it so that it has only 2 decimal places. I wanted to use the toFixed() function for that, but I get the error:
TypeError: props.data.price.toFixed is not a function. I tried to save this number from the props into a local variable and then call toFixed() on it, but the result is the same...
My functional component body:
import React from 'react';
import classes from './Order.module.css';
const order = (props) =>{
let keyTable = [];
for(let igKey in props.data.ingredients){
keyTable.push(igKey, "("+props.data.ingredients[igKey].toString()+")")
}
let ingredientsString = keyTable.join(' ')
return (
<div className={classes.Order}>
<p>Ingrediends: {ingredientsString}</p>
<p>Price: <strong>USD {props.data.price.toFixed(2)}</strong></p>
</div>
);
}
export default order;
The number sent in props: 6.22223
I'd like to just make the number have only 2 decimal places, and rather without using Math.round(). Does anyone know how to do that?
Edit: The problem is fixed when I turned the variable into a number. The error was there because the variable was of type string, and you can't call toFixed() on a string.
Thanks for help everyone! My first question on StackOverflow was resolved in 3 minutes!

You'll get this error if price is not a number. If it looks like a number but isn't, then it is most likely a string.
To convert it to a number, you can use Number(), and then apply toFixed():
var str = '6.22223';
var num = Number(str);
console.log(typeof(num));
console.log(num);
console.log(num.toFixed(2));

Related

What's the difference between manipulating a prop using a constant vs. using a function?

In this approach, I'm checking if propOne is even and then assigning the result to a constant.
import React from 'react';
const TestComponent = ({ propOne }) => {
const isEven = propOne % 2 === 0
return (
<div>
{`Is even? ${isEven ? 'Yes' : 'No'}`}
</div>
);
};
In this other approach, I'm doing the same logic (checking if propOne is even), but instead of assigning the result to a constant, I'm assigning it to a function.
import React from 'react';
const TestComponent = ({ propOne }) => {
const isEven = () => propOne % 2 === 0
return (
<div>
{`Is even? ${isEven() ? 'Yes' : 'No'}`}
</div>
);
};
Besides the obvious difference of having to use isEven() instead of just isEven, what are the differences between these two approaches?
There shouldn't be any difference, given that this is a function component. (Which means using the function is adding a small amount of verbosity for no gain.)
But note that there would be a difference in a class component, if isEven referenced this.props.propOne and were used in (eg) an event handler that is called some time after the render - see this article by Dan Abramov (one of the React developers) for more on this.
The function approach will reevaluate the expression every time you access it. In this specific case, I don't see a lot of benefit since if propOne changes it will cause a re-render anyways.
Based on this specific example, just go with the non-function wrapper version

When trying to find the maximum number in TypeScript, I am getting this error: Type 'string' is not assignable to type 'number'

I am currently learning TypeScript and I am trying to solve this Kata on Codewars. I was able to solve it in JavaScript, but then when I tried solving it in TypeScript, I am getting an error which is explained below. I used the same approach from my JavaScript answer to answer the TypeScript version.
Here is the problem: Given a number, I am to return the maximum number. So if I input 213, I am supposed to return 312 as you see below:
maxNumber (213) ==> return (321)
This is the solution I came up with for JavaScript.
function maxNumber(number) {
var num = String(number).split('').sort().reverse().join('');
return num;
}
const answer = maxNumber(1234)
console.log(answer)
//Output: 4321
I tried the same, but in TypeScript, but I keep getting the error message: Type 'string' is not assignable to type 'number'.
export function maxNumber(n: number): number {
var num = String(n).split('').sort().reverse().join('');
return num;
}
const answer = maxNumber(1234)
console.log(answer)
So then my response to that error was taking the number that is being entered, convert it to a string, then using the split method to convert it back into a number inside of an array, but I am getting the same error message.
export function maxNumber(n: number): number {
var num = n.toString();
var numNew = num.split('').sort().reverse().join('');
return numNew;
}
const answer = maxNumber(1234)
console.log(answer)
I know what it is saying, but I can't assign the type string to n and then return a number. Is there a way to fix this? I know that as a result of using TypeScript, it is supposed to find errors like this, which may not be found when just using JavaScript.
You can use parseInt to return the value as a number:
return parseInt(numNew, 10); // the 10 specifies base 10 (decimal)
Note that even in the Javascript version, you are returning a string not a number, which will be a problem if code calling your functions expects a number and does a comparison on the result or otherwise treats it as an integer, so the solution above should be applied in both cases.

JavaScript: How to explain and understand functions with parameters that seem to have no value?

starting to learn JavaScript and reading the book "Eloquent JavaScript" for starters. I'm having a little difficulty understanding the factor parameter in the hummus function. Can someone help me understand what the starting value of factoris? I can see the values for the ingredient functionbut can't seem to wrap my head around the value of factor. Would appreciate the help!
const hummus = function(factor) {
const ingredient = function(amount, unit, name) {
let ingredientAmount = amount * factor;
if (ingredientAmount > 1) {
unit += "s";
}
console.log(`${ingredientAmount} ${unit} ${name}`);
};
ingredient(1, "can", "chickpeas");
ingredient(0.25, "cup", "tahini");
ingredient(0.25, "cup", "lemon juice");
ingredient(1, "clove", "garlic");
ingredient(2, "tablespoon", "olive oil");
ingredient(0.5, "teaspoon", "cumin");
};
The value of the factor isn't shown here, but any value you input represents the amount of hummus you plan to make. For example hummus(2) would be two batches of hummus.
The inner function ingredient will then establish the amount of each ingredient needed based on the number of batches, and if the ingredient amount (based on amount multiplied by the number of batches) is more than 1 it will add an "s" to the string to make it plural.
What confused me a lot about this example in the book was the introduction of string interpolation here: console.log(${ingredientAmount} ${unit} ${name}). This is not discussed in the book before being introduced here. The back ticks, rather than single or double quotes, are important for the code to recognise the string interpolation.
The example of the output for the hummus function on this page helped me to understand it better.
As did this video on string interpolation.
In the code sample, a function is assigned to a const ingredient
const ingredient = function(amount, unit, name) {
let ingredientAmount = amount * factor;
if (ingredientAmount > 1) {
unit += "s";
}
console.log(`${ingredientAmount} ${unit} ${name}`);
};
Once you have a function you can call it, which is ingredient(1, "can", "chickpeas");
Similarly you need to make a call to hummus, maybe something like hummus(0.3) or hummus(1) passing it a value.
Your code doesn't contain the call to hummus and the value of factor will be set based on the value that you pass to it when making a call.
If hummus is called like hummus() without a value, in that case factor will be set to undefined.
The value of factor isn't shown in your example. Somewhere needs to invoke like var x = hummus(2); or somesuch so you'll know what's being passed in for factor in that instance.

How to access the first two digits of a number

I want to access the first two digits of a number, and i have tried using substring, substr and slice but none of them work. It's throwing an error saying substring is not defined.
render() {
let trial123 = this.props.buildInfo["abc.version"];
var str = trial123.toString();
var strFirstThree = str.substring(0,3);
console.log(strFirstThree);
}
I have tried the above code
output of(above code)
trial123=19.0.0.1
I need only 19.0
How can i achieve this?
I would split it by dot and then take the first two elements:
const trial = "19.0.0.1"
console.log(trial.split(".").slice(0, 2).join("."))
// 19.0
You could just split and then join:
const [ first, second ] = trial123.split('.');
const result = [ first, second ].join('.');
I have added a code snippet of the work: (explanation comes after it, line by line).
function getFakePropValue(){
return Math.round(Math.random()) == 0 ? "19.0.0.1" : null;
}
let trial123 = getFakePropValue() || "";
//var str = trial123.toString();
// is the toString() really necessary? aren't you passing it along as a String already?
var strFirstThree = trial123.split('.');
//var strFirstThree = str.substring(0,3);
//I wouldn't use substring , what if the address 191.0.0.1 ?
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
Because you are using React, the props value was faked with the function getFakePropValue. The code inside is irrelevant, what I am doing is returning a String randomly, in case you have allowed in your React Component for the prop to be empty. This is to show how you an create minimal robust code to avoid having exceptions.
Moving on, the following is a safety net to make sure the variable trial123 always has a string value, even if it's "".
let trial123 = getFakePropValue() || "";
That means that if the function returns something like null , the boolean expression will execute the second apart, and return an empty string "" and that will be the value for trial123.
Moving on, the line where you convert to toString I have removed, I assume you are already getting the value in string format. Next.
var strFirstThree = trial123.split('.');
That creates an array where each position holds a part of the IP addrss. So 19.0.0.1 would become [19,0,0,1] that's thanks to the split by the delimiter . . Next.
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
This last piece of code uses the conditional if to make sure that my array has values before I try to splice it and join. The conditional is not to avoid an exception, since splice and join on empty arrays just returns an empty string. It's rather for you to be able to raise an error or something if needed. So if the array has values, I keep the first two positions with splice(0,2) and then join that array with a '.'. I recommend it more than the substr method you were going for because what if you get a number that's 191.0.0.1 then the substr would return the wrong string back, but with splice and join that would never happen.
Things to improve
I would strongly suggest using more human comprehensible variables (reflect their use in the code)
The right path for prop value checking is through Prop.Types, super easy to use, very helpful.
Happy coding!

Angular JS number filter

I had the following expression in Angular:
<br/><i>{{getFieldValue(teamMember.reportingData.fields, fieldname, 'meanValue' | number:2)}}</i>
where getFieldValue is a function on my controller. This was working as expected, and truncating the numeric result to 2 decimal places.
However, sometimes getFieldValue returns a string result. When that happens, it is not displayed at all. This is probably because truncating a string to 2 decimal places does not make sense.
To get round this, I tried to move the filter inside getFieldValue and only apply it to numeric results. To do this, I need a way of specifying a filter in Javascript, not as an expression in HTML. According to the docs this is possible, but the explanation is hard to follow.
Here is my attempt:
HTML:
<br/><i>{{getFieldValue(teamMember.reportingData.fields, fieldname, 'meanValue')}}</i>
part of getFieldValue :
if (field.numeric) {
fieldValue = $filter('number')([], field[aggregate], 2);
} else {
fieldValue = field[aggregate];
}
This does not work, I get what seems to be an empty string back. How to I do this properly?
Use like this
fieldValue = $filter('number')(field[aggregate], 2);
See Documentation of number filter.
var isnum = angular.isNumber(field[aggregate]);
if(isnum){
fieldValue = $filter('number')(field[aggregate], 2)
}else{
fieldValue = field[aggregate];
}
number filter in angularjs

Categories

Resources