FindIndex value continuously returning as a -1? - arrays

I have the following expressions:
This fetches the ID parameter passed through the URL:
editUserId = this.route.snapshot.paramMap.get('id');
Then i used FindIndex on an array of objects to find the index of an element in the array equal to the above mentioned ID value fetched from the URL:
this.userToUpdate = this.allUsers.findIndex((x: any) => x.UserId === this.editUserId);
(this.allUsers) being my array of objects.
Although the findIndex continuously returns the value -1 ..
I have tried the following two methods, both of which return the same error: "This condition will always return 'false' since the types 'number' and 'string | null' have no overlap":
this.userToUpdate = this.allUsers.findIndex((x: any) => parseInt(x.UserId) === this.editUserId);
this.userToUpdate = this.allUsers.findIndex((x: any) => Number(x.UserId) === this.editUserId);
Any reason as to why this may be happening?

Seventh, I guess that can be the editUserId needs to be number, you can try it:
this.userToUpdate = this.allUsers.findIndex((x: any) => Number(x.UserId) === Number(this.editUserId));
or
editUserId = this.route.snapshot.paramMap.get('id');
editUserId = Number(editUserId)
I guess it because when you return the params to your variable, always it will be string

Related

react check array values based on specific keys returning true/false if values found

I am trying to figure out how to do this but can't seem to wrap my head around it..
I have an address object
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"123 Any Street",
"addressLine2":"",
"city":"Any Town",
"state":"Indiana",
"state_code":"IN",
"zip":"46220-4466",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":"MyCounty"
}
I want to check for any key that has a value but only specific keys
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
I want to check all keys in objProps against my address object and if any one of them contains a value return true (doesn't matter if its 1 or all 6).. If all keys don't contain a value then return false (Sometimes I will get an address object that has all null values)
I've tried various ways to accomplish this but have failed in each one.
The variation I am working on now is using reduce. While it doesn't meet my needs I thought I could check the resulting array and if length was greater than 0 than I have my answer..
Work-in-progress:
function hasAddressData(obj: any) {
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const keysWithData = objProps.reduce((accumulator, key) => {
const propExistsOnObj = obj.hasOwnProperty(key);
let keyHasData = [];
if (obj[key].length > 0 ) {
keyHasData = obj[key]
}
if (!propExistsOnObj) {
accumulator.push(key);
} else if (keyHasData) {
const equalValueKeyIndex = accumulator.indexOf(key);
accumulator.splice(equalValueKeyIndex, 1);
}
return accumulator;
});
return keysWithData;
}
The above is messed up I know and doesn't work.. Just learning this stuff.. anyone have a suggestion or comment?
Check that .some of the objProps, when looked up on the obj, contain a value. (Either with Boolean or by comparing against '')
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"123 Any Street",
"addressLine2":"",
"city":"Any Town",
"state":"Indiana",
"state_code":"IN",
"zip":"46220-4466",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":"MyCounty"
}
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const somePopulated = objProps.some(prop => obj[prop]);
// or prop => obj[prop] !== ''
console.log(somePopulated);
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"",
"addressLine2":"",
"city":"",
"state":"Indiana",
"state_code":"",
"zip":"",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":""
}
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const somePopulated = objProps.some(prop => obj[prop]);
// or prop => obj[prop] !== ''
console.log(somePopulated);
function checkKeys(target, props) {
return props.some((prop) => {
return target.hasOwnProperty(prop) && target[prop];
});
}
Explanation: some iterates through the props you want to check, returning true immediately when one is found (i.e. the callback returns true). If no props are found (i.e. no callback returns true), some returns false.
hasOwnProperty ensures that you are only checking properties on target, and not looking up the prototype chain. target[prop] checks for a truthy value. You may need to modify this last check if you're going to be handling values other than strings.

Error argument of type 'Item' is not assignable to parameter of type 'string'. TS2345

I am getting error with type 'string'. TS2345
Argument of type 'Item' is not assignable to parameter of type
'string'. TS2345
filter(resortList:ResortResult[], selectedFilters:SelectedFilters) {
return resortList
.filter(resort => {
let roomTypes = resort.available.flat().map(room => room.roomType);
let activities = resort.activities;
let hasRoomType = selectedFilters["room"].some(
(rt:Item)=> roomTypes.indexOf(rt) > -1
);
let hasActivity = selectedFilters["activity"].some(
(act:Item) => ((activities.indexOf(act.value)) > -1)
);
return !(
(selectedFilters["area"].length === 0 ||
selectedFilters["area"].indexOf(resort.city) > -1) &&
// (selectedFilters["views"].length === 0 ||
// selectedFilters["views"].indexOf(resort.city) > -1) &&
(selectedFilters["activity"].length === 0 || hasActivity) &&
(selectedFilters["room"].length === 0 || hasRoomType)
);
})
.map(resort => {
return resort.propertyCode;
});
}
How can I fix this error with react-typescript? Thanks alot!
So it looks like you are using typescript. Typescript is a strongly-typed language, meaning that typically you have to define the datatype for a variable before you can use it. This also means that you can only set a variable to the type that it is assigned.
What this error is saying is that you are trying to assign a value that is not a string to a variable where the type is "string". More specifically, it looks like you are trying to assign a whole object (of type "Item") to a variable with the type "string".
You need to check your code and make sure that you are not trying to assign the wrong datatype somewhere. In the small code snippet that you gave, it's a bit difficult to see where the error is.
When you have to assign a type to an array callback, like (rt:Item) => and (act:Item) =>, that's a sign that some type is either missing or incorrect higher up in the chain. The callback will get the correct type automatically if the array itself has the correct type.
It seems like the error is most likely in your indexOf calls, though it's hard to know for sure without seeing your types for ResortResult and SelectedFilters. You are checking that roomTypes contains an element rt which is an Item. If roomTypes is an array of string then you would need to check roomTypes.indexOf(rt.value) instead of roomTypes.indexOf(rt).
If it is in fact an array of Item, you might have confusing results because indexOf is checking for strict equality. That is, it's checking that you have literally the same object instance in both places.
This code passes all type checks, but it might not match your actual types:
interface Item {
value: string;
}
interface ResortResult {
available: {roomType: string}[][];
activities: string[];
propertyCode: string;
city: string;
}
interface SelectedFilters {
room: Item[];
activity: Item[];
area: string[];
}
function filter(resortList: ResortResult[], selectedFilters: SelectedFilters) {
return resortList
.filter(resort => {
let roomTypes = resort.available.flat().map(room => room.roomType);
let activities = resort.activities;
let hasRoomType = selectedFilters["room"].some(
(rt) => roomTypes.indexOf(rt.value) > -1
);
let hasActivity = selectedFilters["activity"].some(
(act) => ((activities.indexOf(act.value)) > -1)
);
return !(
(selectedFilters["area"].length === 0 ||
selectedFilters["area"].indexOf(resort.city) > -1) &&
// (selectedFilters["views"].length === 0 ||
// selectedFilters["views"].indexOf(resort.city) > -1) &&
(selectedFilters["activity"].length === 0 || hasActivity) &&
(selectedFilters["room"].length === 0 || hasRoomType)
);
})
.map(resort => {
return resort.propertyCode;
});
}
TypeScript Playground Link
You have to assign a different value to a variable as you cannot assign a string to all of the variables.

How to avoid Object is possibly null for Typescript value that can be null or undefined

How can I allow nulls/undefined in this reference if the value can actually be null or undefined. My if statement doesn't seem to capture it.
I get error TS2531. Object is possibly 'null'. Please help.
type formatterType = string | number | undefined | null;
export const formatPercent = (value: formatterType, multiplier = 1): string => {
const val = numeral(value);
if (value !== null || value !== undefined) {
if (val.value()) {
return `${val.value() * multiplier}%`;
}
}
return '0%';
};
val is an instance of the Numeral class. The method value() on this class has return type number | null. Therefore, it is illegal to multiply the return value without checking for null. You cannot guard against this by calling val.value() in the if statement, as typescript has no way of knowing whether the two calls will return the same value. You must use a variable for storing the result:
let v = val.value()
if (v) {
return `${v * multiplier}%`;
}

Can't get the data from array react and Firestore

How can I access the value exist from an array? I think I didn't pass the array inside? Any help or advice
var isExist = this.props.isFavorite(this.props.code);
console.log(isExist)
I have this variable isExist containing the response from console below.
[]
client: [id: "LvR05w9v9xrC3r4V1W8g", exist: true]
length: 1
_proto_:Array(0)
How can I access the exist in my array? When I tried isExist[0].exist I'm getting an error. Any help?
isExist.exist = Undefined
isExist[0].exist = TypeError: Cannot read property 'exist' of undefined
favorite method where I am accessing and pushing data to the array
export const isFavorite = (data) => dispatch => {
let exist = [];
var clientQuery = firebase.firestore().collection(path).where('client_id', '==', data);
clientQuery.get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
var data = [];
data.id = doc.id;
data.exist = doc.exists;
exist.push(data)
});
});
return exist;
}
isFavorite returns a function which takes one argument dispatch and returns exist array. You seem to use async code to populate exist array. So when that function returns exist is an empty array []. You either need to continue using promises or use await. And you need to call the function returned by isFavorite.
If this.props.isFavorite and const isFavorite are not the same then add the code for this.props.isFavorite please.
You're creating an array Object. Then the array object {data}[]. So the problem is, the data is actually not only an array but also an object.
Try doing this.
var data;
data.id = doc.id;
data.exist = doc.exist;
exist.push(data);
Now you will have exist data that would be an array of Object.
Then iterate from it.
exist[0].id;
//or try
exist[0].data.id;
//Depends on how you implement your data.
Since client array doesn’t contain object with keys and values I would recommend you to try with array of index with split() to get id value and exist value from array like
Like
var isExist = this.props.isFavorite(this.props.code);
var id = isExist.client[0];
var exist = isExist.client[1];
var idValue = id ? id.split(': '): '';
console.log(idValue);
const existValue = exist ? exist.split(': '): false;
console.log(existValue);
And here change data = []; array to data ={}; object
querySnapshot.forEach((doc) => {
var data = {};
data.id = doc.id;
data.exist = doc.exists;
exist.push(data)
});

Filter array for angular2 + ngrx

I am trying to use this filter in an angular+ngrx app:
fetchById(id: number): Document {
return this.store.select( s => s.documents ).filter( obj => obj.id == id )[0]
}
documents is an array of Documents, and the latter have an id property. The idea is to filter the array to select one document. However, I get this error message:
Property id does not exist on type Document[]. I don't understand the message, since obj is an element of the array, hence a certain object which has an id property. Any ideas on what is wrong here? Thanks!
Let's break down the operations to understand what's going on...
fetchById(id: number): Observable<Document> {
const documents: Observable<Document[]> = this.store.select(s => s.documents);
const filtered: Observable<Document[]> = documents.filter((obj: Document[]) => obj.id == id );
const result: Observable<Document> = filtered.first();
return result;
}
Notice that Observable#filter()'s callback takes an array, not an individual item. This is different from Array#filter() and the cause of the error message. Also, see that I can't retrieve the first item from an observable with [0], use first() instead. Then I changed the return type to return an observable.
Yet, it doesn't work. When we think about filtering an array from an observable, probably we want to use Observable#map() to produce another array with a single element.
fetchById(id: number): Observable<Document> {
return this.store
.select(s => s.documents)
.map(list => obj.find(obj => obj.id === id));
.first();
}
If we want to return the last value of the observable, we can do this:
fetchById(id: number): Document | null {
let result: Document | null = null;
this.store
.select(s => s.documents)
.map(list => obj.find(obj => obj.id === id) || null);
.first()
.subscribe(item => result = item);
return result;
}
I typed it with | null because the document with the specified id may not exist.

Resources