Define variable status by priority - javascript

I have a situation here.
I want to define a search status based on some priorities.
this are the possible status: notGenerated, generated, processing, invalidInput
I have a array like this:
['notGenerated', 'generated', 'generated', 'processing', 'invalidInput']
the priority is, if some element on array has 'notGenerated' the search status is 'notGenerated'
for the search status be 'generated', the elements on array cant be 'processing' or 'notGenerated', and need to has 'generated' in some of them.
for the search status be 'processing', some element on array must be 'processing' and the elements on array cant be 'notGenerated'.
for the 'invalidInput', we need that every element on the array be 'invalidInput'.
I make this code but i think its very ugly, how can i improve it?
resultsStatus = ['someStatus', 'someStatus', 'someStatus']
let searchStatus;
const hasNotGenerated = resultsStatus.includes('notGenerated');
const hasProcessing = resultsStatus.includes('processing');
const hasGenerated = resultsStatus.includes('generated');
const allInvalidInput = resultsStatus.filter((result) => result.status === 'invalidInput');
if (hasNotGenerated) searchStatus = 'notGenerated';
if (hasGenerated && !hasProcessing) searchStatus = 'generated';
if (resultsStatus.length === allInvalidInput.length) searchStatus = 'invalidInput';
return searchStatus;

You can just define "exit points" from your function, as soon as a criterion is satisfied.
Additionally, it's preferable to use an enum, as it guarantees no typos or other inconsistencies in your statuses.
const Status = {
NOT_GENERATED: 'notGenerated',
GENERATED: 'generated',
PROCESSING: 'processing',
INVALID: 'invalidInput',
};
function determineStatus(arr) {
if (arr.includes(Status.NOT_GENERATED)) return Status.NOT_GENERATED;
// If the array included 'notGenerated', it'd be returned on the previous check
if (arr.includes(Status.PROCESSING)) return Status.PROCESSING;
// If the array included 'notGenerated' or 'processing', it'd be returned on the previous checks
if (arr.includes(Status.GENERATED)) return Status.GENERATED;
if (arr.every(element => element === Status.INVALID)) return Status.INVALID;
}

Related

I am getting an array from JSON and value from the input field when I written logic to the input value is contained array it always returns false

I am working on a project. I am getting an array from JSON and value from the input field when I written logic to the input value is contained array it always returns false.
When I tried returns true or false based on the input value. But the problem is when I implemented the logic into my angular project it's always returns "false"
Here is an example code:
const arrayJSON = ["122318", "196035", "1242865"];
const inputField = 1242865;
const isAvailable = arrayJSON.includes(JSON.stringify(inputField));
console.log('The value is available', isAvailable);
This code return true or false in my local Please find the attachement
When I implemented same logic in my angular project always getting "false" only. What I missed here.
here is the angular code:
const inputValue = this.producerAddRemove().value;
const isAvailable = this.dataSource.data.map(res => res.ProducerID);
const isTrue = isAvailable.includes(JSON.stringify(inputValue));
console.log('is the value existing ', isTrue);
Update:
I just removed JSON.stingify(inputValue) and added only inputValue as per #randomSoul comment. Because the input value already in a string so we don't want to convert again. Thank you all.
I would advise to use built in function indexOf to determine whether array contains value or not:
const arrayJSON = ["122318", "196035", "1242865"];
const inputField = 1242865;
const isAvailable = arrayJSON.indexOf(inputField.toString()) !== -1;
console.log('The value is available', isAvailable);

Extracting specific values from an array within an object

I'm setting up a test to ensure that a faceted Solr query 'contents' are correctly displayed within a page element, using javascript.
The Solr query result, which I've named "ryanlinkstransmissionpage", is;
{ Transmission: [ 'Manual', 12104, 'Automatic', 9858 ] }
What I would like to do is extract the 'Manual' and 'Automatic' only, so I can then test that these values are displayed on a page.
However, it is more the functionality involved in this that I cannot get my head around, as I will be using this method on other Solr query results.
To possibly complicate things, this Solr query result "ryanlinkstransmissionpage" is from a dynamic 'live' Solr, so the values may change each time it's run (so there may be more or less values within this array when it's tested on the following day for example).
I've tried a few javascript commands, but to no avail.
JSON.parse(ryanlinkstransmissionpage)
JSON.stringify(ryanlinkstransmissionpage)
Object.values(ryanlinkstransmissionpage)
Any help would be greatly appreciated. Thanks.
If possible, i highyl recommend changing the transmission field to be an object, rather than an array. That will give you far greater ability to read the data within.
Ignoring that, are you looking to extract the string values and the number values that follow them? ie. "Manual" and "12104"? Or are you simply trying to assert that the string values are present on the page?
Either way, here are two possible approaches.
const ryanlinkstransmissionpage = { Transmission: [ 'Manual', 12104, 'Automatic', 9858 ] };
// Pull out the string values
const strngVals = ryanlinkstransmissionpage.Transmission.filter(val => typeof val === 'string');
// Pull out the string values and the numbers that follow
const strngNumVals = ryanlinkstransmissionpage.Transmission.reduce((keyVals, val, idx, srcArr) => {
if (typeof val === 'string') keyVals[val] = srcArr[idx + 1];
return keyVals;
}, {});
The reduce approach is not stable or robust to changes in data provided from this Solr query result you refer to, nor is it tested. #shrug
Javascript has a built in method called Array.prototype.find(() =>). If you just want to check if this value exists to ensure its on the page, you can simply do:
const ryanlinkstransmissionpage = { Transmission: [ 'Manual', 12104, 'Automatic', 9858 ] };
const manual = ryanlinkstransmissionpage.Transmission.find((ele) => ele === 'Manual'); // returns 'Manual'
const automatic = ryanlinkstransmissionpage.Transmission.find((ele) => ele === 'Automatic'); // returns 'Automatic'
console.log(automatic);
console.log(manual);
// or
const findInArray = (arr, toFind) => {
const result = arr.find((ele) => ele === toFind);
return !!result;
}
console.log(findInArray(ryanlinkstransmissionpage.Transmission, 'Automatic')); // true
console.log(findInArray(ryanlinkstransmissionpage.Transmission, 'HelloWorld')); // false
console.log(findInArray(ryanlinkstransmissionpage.Transmission, 'Manual')); // true

Setting the array status based on the object status in the array

I have an Array of Objects and each object has a status property,It may be pass or Fail or Skipped.If the Object status is other than 'pass', then i have to set the array status has fail irrespective of the number of objects in array and irrespective object with status pass.
singleTestMethod=[
{'status':'PASS'},
{'status':'PASS'},
{'status':'FAIL'},
{'status':'SKIPPED'},
'arrayStatus':'']
i expect the array status should only be set to pass when all the object status in the array are pass otherwise it should be set to fail only.
As what I understand, you want to know if all the objects has a status of pass, else it is considered fail right?
Then:
const testArr1 = [
{status:'PASS'},
{status:'PASS'},
{status:'FAIL'},
{status:'SKIPPED'},
{arrayStatus:''}]
const testArr2 = [
{status:'PASS'},
{status:'PASS'}]
const checkArray = (testArr) => !testArr.find(each => each.status !== 'PASS')
console.log(checkArray(testArr1)) // false
console.log(checkArray(testArr2)) // true
I think that you made a typo in writing your array, I took the freedom to fix it.
Because of a lack of clarity in your request I also assume that your structure will always be identical so 'arrayStatus' will be the last item of the array.
What I understood is that you want to check all the 'status' values in the array.
If all are 'PASS' then 'arrayStatus' must become 'PASS' too, otherwise 'arrayStatus' must become 'FAIL'.
If the above assumptions are right please try the following code:
var singleTestMethod=[
{'status':'PASS'},
{'status':'PASS'},
{'status':'FAIL'},
{'status':'SKIPPED'},
{'arrayStatus':''}];
console.log("singleTestMethod array before its check:")
console.log(singleTestMethod);
function setArrayStatus(myArray){
var totalItems = myArray.length - 1;
var totalPass = 0;
myArray.forEach(function(entry) {
if (entry.status === "PASS"){
totalPass++;
}
});
if (totalItems === totalPass){
myArray[myArray.length - 1] = {'arrayStatus': 'PASS'};
} else {
myArray[myArray.length - 1] = {'arrayStatus': 'FAIL'};
}
return myArray;
}
singleTestMethod = setArrayStatus(singleTestMethod);
console.log("singleTestMethod array after its check:")
console.log(singleTestMethod);
Thanks for your answers,i have tried it using the object filter property has follows..
var singleTestMethod = [
{'status':'PASS'},
{'status':'FAIL'},
{'status':'SKIPPED'},
{'arrayStatus':''}];
const result = singleTestMethod.filter(singleTestMethod =>
singleTestMethod.status === 'FAIL' || singleTestMethod.status === 'SKIPPED');
console.log(result);
if(result.length == 0){
singleTestMethod.arrayStatus = 'PASS';
}else{
singleTestMethod.arrayStatus = 'FAIL';
}
console.log( singleTestMethod.arrayStatus);

Remove element in Typescript Interface List when entry present, always displaying negative index

I have an interface:
export interface ISchoolsPreview {
// Shared
AgeID: string;
School_name?: string;
}
I have a function triggered by a change in a Checkbox:
onChange(code: string, name: string, check: boolean): void {
const tempPreview: ISchoolsPreview = {AgeID: code, School_name: name};
if (check) {
this.schoolsPreview.push(tempPreview);
} else {
//This is where the error lies
const index = this.schoolsPreview.indexOf(tempPreview);
if (index > -1) {
this.schoolsPreview.splice(index, 1);
}
}
}
Check is defined by whether the checkbox was checked or uncheched. If checked it adds a new element of ISchoolsPreview to schoolsPreview. This works and when I step through it shows up and displays correctly on my front end.
However when I uncheck a checkbox, the indexOf(tempPreview) always returns -1 even if I am passing the same entry.
How do I correctly remove an element from my Interface List
You should always find the index of the object based on some property in the object rather than using the whole object itself as follows.
const index = this.schoolsPreview.findIndex((obj) => obj['Property'] === code);
If you thing you will have duplicate codes in the array, then you might have to generate unique ids for each objects and search based on that Id.
Note: I am not sure on this, but passing object to index while return true only if the object references to the same memory. If its a new object you are trying to find, which is in new memory, it might return false. Someone can correct me on this.
I have fixed this by changing:
const index = this.schoolsPreview.indexOf(tempPreview);
to:
const index = this.schoolsPreview.findIndex(s => s.AgeID === code);

Steam API, different json format

Recently i integrated CSGO stats in my discord bot, but today i saw that for almost every player the API sends a different json data.
Here 2 examples:
https://jsonblob.com/58688d30-26d0-11e8-b426-7b3214778399
https://jsonblob.com/52ed0c3f-26d0-11e8-b426-43058df4a5a6
My question was how to request the data properly so a win is really a win and not a kill.
.addField('**Wins:**', `${object.playerstats.stats[5].value}`, true)
.addField('**Time played:**', `${object.playerstats.stats[2].value}` + ' minutes', true)
.addField('**Kills:**', `${object.playerstats.stats[0].value}`, true)
.addField('**Deaths:**', `${object.playerstats.stats[1].value}`, true)
.addField('**Bombs planted:**',`${object.playerstats.stats[3].value}`, true)
.addField('**Money earned:**',`${object.playerstats.stats[7].value}`, true)
.addField('**Knife kills:**',`${object.playerstats.stats[9].value}`, true)
.addField('**Headshot kills:**',`${object.playerstats.stats[24].value}`, true)
.addField('**Dominations:**',`${object.playerstats.stats[39].value}`, true)
.addField('**Rounds played:**',`${object.playerstats.stats[44].value}`, true)
The name property of stats items appear to be unique enough to find. You can use array.find to look for the correct stat by name.
const stats = object.playerstats.stats
const totalKills = stats.find(s => s.name === 'total_kills').value
const totalDeaths = stats.find(s => s.name === 'total_deaths').value
Taking it further, you can use array.reduce to generate an object whose key is name and value is value for each item in the array. This way, you access it like an object.
const stats = object.playerstats.stats
const statsObj = stats.reduce((c, e) => (c[e.name] = e.value, c), {})
const totalKills = statsObj.total_kills
const totalDeaths = statsObj.total_deaths
Rather than trying to reference the array indexes, why not convert the API response into an easier-to-parse format?
// do this once...
let playerStats = {};
object.playerstats.stats.forEach(s => playerStats[s.name] = s.value);
// ...then you can use the playerStats variable however you need:
.addField('**Kills:**', `${playerStats.total_kills}`, true)
.addField('**Wins:**', `${playerStats.total_wins}`, true)
The stats array is just not sorted. you can use .find() to get the correct entry from the stats.
for example
const totalWins = object.playerstats.stats.find(stat => {
return stat.name === 'total_wins';
});
.addField('**Wins:**', `${totalWins.value}`, true)
You are approching this problem the wrong way.
JSON is not a format that is ordered. What that means is that there is no guarantee that the JSON data will return in the same order everytime. It is not a default of the API.
There is one way you could still use your way: by sorting the 'stats' array by name. but it is a long operation and not a very good idea.
The way do to this is to do a lookup by name.
For example, if you want to find the wins, you do this :
object.playerstats.stats.find(elem => elem.name === 'total_wins').value;
The find function does a lookup and returns the first element matching the predicate (elem.name === 'total_wins'). It returns null if not element matched the predicate (so be careful here).
You could do a function that returns a value for you :
findValue(statsArray, name) {
const entry = statsArray.find(elem => elem.name === name);
return entry ? entry.value : '?';
}
And then your code would look like this :
...
.addField('**Wins:**', findValue(object.playerstats.stats, 'total_wins'), true)
...
The main thing here is : never assume fields in a JSON will return the same every time. Always use lookup, and not indexes (unless it is sorted).

Categories

Resources