reactjs OR condition breaks in the second comparison - javascript

I'm trying to add different Id to a component based on a certain value.
My approach is like below
id={activePage === ('dashboard' || 'evc_detail')? 'bg_gradient':'bg_normal'}
In this scenario if the activePage is equal to dashboard the correct id is added but it does not register if activePage is equal to evc_detail. Is the way i'm using this condition wrong and how can i solve this?

If you want to multiple comparisons you'll need to state them manually:
(activePage === 'dashboard' || activePage === 'evc_detail') ? 'bg_gradient' : 'bg_normal'
Another option is create an array of items (or a Set), and use Array.includes() (or Set.has) to check if an item is in the group:
const gradientPages = ['dashboard', 'activePage']
gradientPages.includes(activePage) ? 'bg_gradient' : 'bg_normal'
Your original expression activePage === ('dashboard' || 'evc_detail')? 'bg_gradient':'bg_normal' doesn't work if the activePage is not 'dashbarod' because of the way it's evaluated:
'dashboard' || 'evc_detail' is evaluated, since 'dashboard' is a truthy expression, the result is always dashboard.
'dashboard' is compared with activePage. If activePage is 'dashboard' the result is true, if not it's false.

Related

ReactJS: Map and Find

Introduction
I have a search filter in which I enter parameters such as sender and recipient.
In this way for the sender I make a call and get results.
For the recipient I make another call and get other results.
So I will have two arrays:
sent
sent1
what I would like to do is iterate through the first arrival comparing each element with each element of the second array and if a certain condition is exceeded save the element of the first array.
Now my Code is:
let filteredSent = {rows: []}
sent.rows.map( (elem) => { sent1.rows.find( (value) => {
if(value.key[2] === values.recipient.Code && value.key[0] === "RECIPIENT" && elem.key[1] === value.key[1] && elem.key[3] === value.key[3] && elem.value === value.value){
filteredSent.rows.push(elem)
}
})
} )
where values.recipient.Code is an input value that I choose from a list.
My problem is that I make this comparison, but I find myself certain results that shouldn't be there.
Is what I'm doing the map and find a wrong use?
Thank you all for your time.

JS only execute if statement based on condition

I am fetching data from an api and I need to render a component based on an if statement and I cant seem to figure it out. A customer has an array of roles. Customer.items is an array of customer objects. This is the if statement I am trying but doesnt work:
{customers?.items?.length > 1 && !roles.includes("Super") && (...component
Basically I need to check if roles array has "Super" and customers.items only has one element then dont render the component.
Also if roles is "Super" and customer.items.length > 1 then still render the component
customers.items: [{id: 2, name: "G"}, {id: 3, name: "H"}]
roles: ["Super", "Admin"]
This will render the component in all cases except when customers.items has only one element and if the roles include 'Super'.
const hasSingleCustomer = customers?.items?.length === 1
const hasSuperRole = roles.includes('Super'))
{!(hasSingleCustomer && hasSuperRole) && <Component />}
You can also write it as {(!hasSingleCustomer || !hasSuperRole) && <Component />} if you prefer.
You can try this approach
{(customers.items.length > 1 && roles.includes("Super")) ? <If Success Component/> : <Failure Component>}
I have written as per your request, as I am checking if the roles array has "Super" in it, You can still manipulate the operation inside the brackets(), and we have to use ? and : to make sure the conditions work,
Happy Coding :)
My suggestion is to split the equation/ conditions into smaller variables and then use them to create a validity condition. This way, your code is more readable and easier to maintain
const length = customers.items.length
const isSuperUser = roles.includes('Super')
const isAdminUser = roles.includes('Admin')
const isAllowedForSuper = isSuperUser && length === 1
const isAllowedForAdmin = isAdminUser && length === 0
if (isAllowedForSuper || isAllowedForAdmin) {
return <Component {...props} />
}
return null

Typescript error This condition will always return 'true' since the types have no overlap

I having this condition on a form group:
if((age>17 && (this.frType=="Infant"))
|| (age>40 && this.frType=="Grandchild")
|| (age<=5 &&
(this.frType!="Child"
|| this.frType!="Infant"
|| this.frType!="Grandchild" || this.frType!="Cousin")))
It contain 3 main conditions:
If a person aged 17, cannot be set to infant
If a person is bigger than 40, he cannot be a grandchild
If a person is less than 5 years, he should be child, infant, grandchild or cousin.
If one of these conditions is true, I will send an error message.
The error I am receiving is:
[ts] This condition will always return 'true' since the types
'"Child"' and '"Infant"' have no overlap. [2367]
On this part of the if condition`:
|| this.frType!="Infant" || this.frType!="Grandchild" || this.frType!="Cousin")))
I am using the exact condition in a different component, and it does not show an error.
if((age>17 && (this.family_relation_type=="Infant"))
|| (age>40 && this.family_relation_type=="Grandchild")
|| (age<=5 &&
(this.family_relation_type!="Child" ||
this.family_relation_type!="Infant" ||
this.family_relation_type!="Grandchild" ||
this.family_relation_type!="Cousin")))
Here is how I am calculating the age in both components:
let timeDiff = Math.abs(Date.now() - this.formGroup.controls['dob'].value);
let age = Math.floor((timeDiff / (1000 * 3600 * 24))/365);
Consider the standalone expression:
(this.frType!="Child" || this.frType!="Infant")
If frType is Child, the second part will be true, so the expression will evaluate to true. If frType is Infant, then the first part will be true, so the expression will evaluate to true. If frType is neither Child nor Infant, then the first part will be true, and the expression will, again, evalute to true - the logic is faulty, it'll always resolve to true.
(If you add additional || conditions for Grandchild and Cousin, the same thing keeps happening - it'll always resolve to true)
Either use && instead:
|| (age<=5 && (
this.frType!="Child"
&& this.frType!="Infant"
&& this.frType!="Grandchild"
&& this.frType!="Cousin"
))
Or, to make the logic easier to follow, you might consider using an array, and use .includes:
const kidsFiveAndUnder = ['Child', 'Infant', 'Grandchild', 'Cousin'];
// ...
|| (age <= 5 && !kidsFiveAndUnder.includes(this.frType))
Maybe i can help someone with this.
In my case the error was triggered by:
*ngIf="fooArray.length === 0"
so i modified it to be:
*ngIf="fooArray.length < 1"
Makes no sense to me, but it works.
I struggled with this problem recently. Sharing my experience here
Basically IDE does not allow to compare an object.enum with a string. As a solution, a method in the component.ts is added to compare the enum
Details :
export enum Status {
NEW,
PROGRESS,
FINISHED
}
export interface Model {
id : number;
name : string;
status : Status
}
Now in the component.html, I was trying to compare the model status
<div *ngFor="let m of modelItems" >
<i *ngIf="m.status === 'NEW'" class="icon-new"></i>
</div>
Error : This condition will always return 'false' since the types 'Status' and 'string' have no overlap.ngtsc(2367)
I also tried defining the status enum in the component.ts and used that for comparison
public StatusEnum = Status;
<div *ngFor="let m of modelItems" >
<i *ngIf="StatusEnum[m.status] === 'NEW'"
class="icon-new"></i>
</div>
With the above solution, there is no IDE error, but the condition never true, as the enum[value] give a numeric value.
The next option I tried was as follows
<div *ngFor="let m of modelItems" >
<i *ngIf="m.status=== StatusEnum[StatusEnum.NEW]" class="icon-new"></i>
</div>
But ended up with the error again in the IDE
Error : This condition will always return 'false' since the types 'Status' and 'string' have no overlap.ngtsc(2367)
Finally what solved the issue it implement a method in the component.ts
Solution
component.ts
public StatusEnum = Status; //To refer in the HTML
checkStatus(m: Model, status: Status): boolean {
return Status[m.status] as unknown === status;
}
Note : Status[m.status] as unknown
HTML
<div *ngFor="let m of modelItems" >
<i *ngIf="checkStatus(m,StatusEnum.NEW)"
class="icon-new"></i>
</div>
Define the data types of all your variables explicitly.
For example, this code has the same error mentioned in the thread title and I fixed by defining the data types of the variables explicitly.
From:
const selectedLangCulture = "en"; // or "ar-SA"
const direction = "rtl";
const languageChanged =
(direction === "rtl" && selectedLangCulture === "en") ||
(direction === "ltr" && selectedLangCulture === "ar-SA");
To:
const selectedLangCulture: string = "en"; // Put the datatype string.
const direction: string = "rtl"; // Put the datatype string.
const languageChanged =
(direction === "rtl" && selectedLangCulture === "en") ||
(direction === "ltr" && selectedLangCulture === "ar-SA");
In my case, I was using a type named type for the button element with React.ComponentPropsWithRef<'button'>
type ButtonProps = {
type?: 'submit' | 'button' | 'link'; // ❌
} & React.ComponentPropsWithRef<'button'>;
the type was overridden because React.ComponentPropsWithRef<'button'> had a type in it also. I replaced it with elementType and the problem is solved.
type ButtonProps = {
elementType?: 'submit' | 'button' | 'link'; // ✅
} & React.ComponentPropsWithRef<'button'>;
In my case, I simply had to rebuild my app because the type definitions got briefly out of sync.

Using Filter Function to Find Values Equal to False and Setting to True

In my Angular app I have a function that drills down to an array, and then uses a filter function to pull out values in a new array where "completed" is "false".
This is working as expected. And the way our data is, there is always one object in the array that has the property for "completed" set to "false", so I can target [0] to get to that. So, from there all I need to do is set it to "true". However, for whatever reason, how to accomplish this last step is eluding me.
This is my whole function, and what I've tried thus far:
private completeLastWorkflowStatus() {
let currentService = this.checkDiscipline();
for (let service of this.client.services) {
if (service.service === currentService) {
let targetWorkflow = service.workflow;
let inCompleteWorkflow = targetWorkflow.filter(workflow => workflow.completed === false);
console.log(inCompleteWorkflow);
if (inCompleteWorkflow[0].completed === false) {
inCompleteWorkflow[0].completed === true;
console.log(inCompleteWorkflow[0].completed);
}
}
}
}
For the last console.log listed above, I still get "false" as the value. What am I missing here? How can I set the value of "completed" to "true" for this one object in the array?
inCompleteWorkflow[0].completed === true; is not assignment. Do inCompleteWorkflow[0].completed = true;

javascript checking multiple conditions in if statement

I have an if statement which checks multiple conditions. I would like it to skip the conditional statement if at least one thing returns false. I can see that it is currently picking up the conditional statement if at least one thing is true.
if((api != 'abosp') || (api !='sersp') || (api !='volsp') || (api !='consp') || (api !='givsp') || (api !='blosp')){
console.log("api: " + api );
api = 'cussp'
}
What would be the correct way to implement this kind of logic?
Currently if api == 'abosp' it will still pass into the conditional statement instead of skipping it.
You should change your || for and operator: &&. Still, a more "clean" method would be:
banned = ["abosp", "sersp", "volsp", "consp", "givsp", "blosp"]
if(banned.indexOf(api) == -1){ // if api is not in list
console.log("api: " + api );
api = 'cussp'
}
Actually your if can't be evaluated to true since api can't be all the values you check. I guess you need an and (&&) instead of an or (||):
if ((api != 'abosp') && (api !='sersp') && ...
In this case, you can use an associative array to have more succinct code:
d = {abosp: 1, sersp: 1, volsp: 1, consp: 1, givsp: 1, blosp: 1};
if (!d[api]) api = 'cussp';
I think you are looking for && rather than ||.
This will skip the conditional statement if any of the individual comparisions return false.

Categories