How to make search case insensitive in Angular - javascript

I have a list of data names and I want to search through it. It should give result irrespective of the case.
this is what I have:
public groups = [{ name: '"Grx-1"', selected: false }, { name: '"Grx-man-2"', selected: false }, { name: '"Grx-up-3"', selected: false }];
queryGroups(groupName) {
this.groups = this.totalGroupsList.filter((group) => {
if (group.userId.includes(groupName) || group.dps.includes(groupName) || group.sourceType.includes(groupName)) {
return true;
} else {
let isRole = false;
group.role.forEach((role) => {
if (role.name.includes(groupName)) {
isRole = true;
return;
}
});
if (isRole === false) {
return false;
} else {
return true;
}
}
});
}
If I search for "Grx" I get all the results. I want that if I search for "grx" i should get all the results.

You can use toLowerCase()
role.name.toLowerCase().includes(groupName.toLowerCase())

You must use more than one search method :
queryGroups(groupName: string) {
this.groups = this.totalGroupsList.filter((group) => {
let isExist = this.searchFunc(groupName, group.userId)
|| this.searchFunc(groupName, group.dps)
|| this.searchFunc(groupName, group.sourceType)
if (isExist) {
return true;
} else {
let isRole = false;
group.role.forEach((role) => {
if (this.searchFunc(groupName, role.name)) {
isRole = true;
break;
}
});
return isRole !== false;
}
});
}
private searchFunc(searchKey, searchTarget): boolean {
if(!searchKey) {
return false;
}
return (searchTarget.toLocaleUpperCase().includes(searchKey.toLocaleUpperCase())) ||
(searchTarget.toUpperCase().includes(searchKey.toUpperCase())) ||
(searchTarget.includes(searchKey.toLocaleUpperCase())) ||
(searchTarget.includes(searchKey.toUpperCase())) ||
(searchTarget.toLocaleUpperCase().includes(searchKey)) ||
(searchTarget.toUpperCase().includes(searchKey)) ||
(searchTarget.includes(searchKey))
}

Related

Checking if there is a value in the Array hierarchy

I want to check if there is a value in a certain variable I have. Below I put an example of a logic that I want to achieve.
No matter how hard I tried, I was able to write a very sketchy code as a result of 3 hours of work and research, but it has nothing to do with what I want to achieve.
My Code:
const Files = [
{
Name: 'System',
Type: 'directory',
Value: [
{
Name: 'Main',
Type: 'directory',
Value: [
{
Name: 'Drivers',
Type: 'directory',
Value: [
{
Name: 'Startup',
Type: 'file',
Value: new FileSystem.File('Startup', 0x1, 'test blah blah'),
},
],
},
],
},
],
},
];
BlahBlah.has(Files, 'System->Main->Drivers');
// [File]
BlahBlah.has(Files, 'System->Main->Drivers->Startup');
// File
BlahBlah.has(Files, 'System->Main->Drivers->AnyWhere');
// undefined
BlahBlah.has(Files, 'System->Main->AnyRandomDirectory');
// NaN
My Function:
function text2Binary(str: string, spliter: string = ' '): string {
return str
.split('')
.map(function (char) {
return char.charCodeAt(0).toString(2);
})
.join(spliter);
}
export function FileTypeFromNumber(e: number) {
if (typeof e != 'number')
try {
e = Number(e);
} catch (_) {
return null;
}
return {
0x1: {
Name: 'Executable File',
Extension: 'exe',
},
0x2: {
Name: 'Text Document',
Extension: 'txt',
},
}[e];
}
export type FileTypes =
| 0x1
| 0x2
| 0x3
| 0x4
| 0x5
| 0x6
| 0x7
| 0x8
| 0x9
| null;
export class File {
Name: string;
Type: {
Name: string;
Extension: string;
};
Content: string;
Size: number;
constructor(name: string, type: FileTypes, content: string) {
this.Name = name;
this.Type = FileTypeFromNumber(type);
this.Content = content;
this.Size = text2Binary(content, '').length;
}
}
export class Directory {
public Name: string;
public Files: (File | Directory)[] = [];
constructor(name: string) {
this.Name = name;
}
addFile(file: File | Directory) {
this.Files.push(file);
}
getFile(name: string): null | (File | Directory)[] {
if (typeof name != 'string')
try {
name = String(name);
} catch (_) {
return null;
}
const Result = this.Files.filter((e) => e.Name == name);
return Result.length == 0 ? null : Result;
}
getSize() {
return this.Files.map((e) =>
e instanceof Directory ? e.getSize() : e.Size
).reduce((a, b) => a + b, 0);
}
has(name) {
return this.Files.some((e) => e.Name == name);
}
getJSON() {
return this.Files.map((e) => ({ ...e }));
}
}
interface x {
Content: string;
Name: string;
Size: number;
Type: string;
}
export function ConvertFromJSONtoDirectory(json: any[]) {
return json.map((value) => {
const isDirectory = value.Type == 'directory';
if (!isDirectory) {
return value.Value;
}
const self = new Directory(value.Name);
ConvertFromJSONtoDirectory(value.Value).map((e) => self.addFile(e));
return self;
});
}
export default class DirectorySystem {
Memory: Map<any, any>;
Current: string | null;
constructor(Current = null) {
this.Memory = new Map();
this.Current = Current;
}
addDirectory(directory: Directory): null | true {
if (!(directory instanceof Directory)) return null;
if (this.Memory.has(directory.Name)) return null;
this.Memory.set(directory.Name, directory);
return true;
}
getDirectory(DirectoryName: string): boolean | Directory {
if (typeof DirectoryName != 'string')
try {
DirectoryName = String(DirectoryName);
} catch (_) {
return null;
}
const Result = this.Memory.has(DirectoryName);
return Result ? this.Memory.get(DirectoryName) : Result;
}
getDirectoryCurrent() {
if (this.Current == null) return this;
}
changeDirectory(by: -1 | 1, value: string) {
if (by == -1) {
if (this.Current == null) return null;
if (this.Current.includes('->')) {
this.Current = this.Current.split('->').slice(0, -1).join('->');
} else {
this.Current = null;
}
return this.Current;
} else if (by == 1) {
let Position = [this.Current, value].join('->');
if (this.Current == null) {
Position = Position.split('->').slice(1).join('->');
}
let Result = this.has(Position);
console.log(Result);
}
}
has(query: string) {
try {
return query.split('->').reduce((a, b) => {
if (Array.isArray(a)) {
const f = a.filter((e) => e['Name'] == b);
if (a.length > 0) {
return f['Files'];
} else {
return a;
}
}
return a['Files'];
}, this.getJSON());
} catch (_) {
return false;
}
}
getJSON(): x[][] {
return [...this.Memory.values()].reduce((a, b) => {
a[b.Name] = b.getJSON();
return a;
}, {});
}
}
Result: (Thanks Michael M. and chill 389cc for helping me understand the error)
has(
query: string,
overwrite = null
) {
// If overwrite argument is not null, we are going use it.
let files = overwrite == null ? this.getJSON() : overwrite;
// Split string for getting more usable type with converting string to Array.
const QueryParams = query.split('->').filter(String);
// If we dont have no query, we can return current status.
if (QueryParams.length == 0) return overwrite;
if (Array.isArray(files)) {
const SearchFor = QueryParams.shift();
const Result = files.filter((e) => {
if (e instanceof Directory) {
const x = e.Name == SearchFor;
return x ? e : false;
}
return e.Name == SearchFor;
})[0];
// If we cant find any indexing result
if (!Result) return false;
// We found a file and if we dont have any query this is mean we found it!
if (Result instanceof File) return QueryParams.length == 0;
// We found a Directory and we doesnt have any Query now, so we can return true.
if (Result instanceof Directory && QueryParams.length == 0) return true;
if (
Result.Name != SearchFor ||
(QueryParams.length != 0 && Result.Files.length == 0)
)
// If name not suits or still we has Query and not enough file for indexing.
return false;
// If nothing happens on upper section, return rescyned version of this function.
return this.has(QueryParams.join('->'), Result.Files);
} else {
// If value is Object, Try Search param in object, and return it.
const Result = files[QueryParams.shift()];
return !Result ? false : this.has(QueryParams.join('->'), Result);
}
}
I can't replicate all of your code, but does this help?
interface Entry {
Name: string,
Type: string,
Value: Array<Entry> | any,
};
const Files = [
{
Name: "System",
Type: "directory",
Value: [
{
Name: "Main",
Type: "directory",
Value: [
{
Name: "Drivers",
Type: "directory",
Value: [
{
Name: "Startup",
Type: "file",
Value: "test", // change this to anything
},
],
},
],
},
],
},
];
function getEl(files: Array<Entry>, path: String) {
let path_walk = path.split("->");
let obj = files;
for (let part of path_walk) {
let found = false;
for (let entry of obj) {
if (entry.Name == part) {
obj = entry.Value;
found = true;
}
}
if (!found) return undefined;
}
return obj;
}
console.log(getEl(Files, "System->Main->Drivers")); // => [ { Name: 'Startup', Type: 'file', Value: 'test' } ]
console.log(getEl(Files, "System->Main->Drivers->Startup")); // => "test"
console.log(getEl(Files, "System->Main->Drivers->AnyWhere")); // => undefined
console.log(getEl(Files, "System->Main->AnyRandomDirectory")); // => undefined
There are some obvious problems, such as the fact that your example shows .has() being called with two arguments but it is defined in the class to only take in one. That being said, here is a function that, given a string query as you have and an array of objects like you have, would read the query and return if the array works for that query.
function has(fileSystem, query) {
const arrayOfArgs = query.split('->')
if (Array.isArray(fileSystem)) {
for (let i = 0; i < fileSystem.length; i++) {
if (fileSystem[i]['Name'] === arrayOfArgs[0]) {
if (arrayOfArgs.length === 1) {
// element found
return true; // replace this to return an actual value if that is desired.
}
if (fileSystem[i]['Type'] === 'directory') {
// if not, recurse in if it is a directory
return has(fileSystem[i]['Value'], arrayOfArgs.slice(1).join('->'));
} else {
// if it isn't a directory, don't try to recurse in
return false;
}
}
}
}
return false;
}
console.log(has(Files, 'System->Main->Drivers')); // true
console.log(has(Files, 'System->Main->Drivers->Startup')); // true
console.log(has(Files, 'System->Main->Drivers->AnyWhere')); // false
console.log(has(Files, 'System->Main->AnyRandomDirectory')); // false
You'll have to add your own types to get it back to TypeScript and obviously I pulled it out of the class for easier testing but it should be pretty easy to re-implement.

How to write unit test with Jasmine-Karma in Angular?

I have two functions I need to write unit test for it. I tried some test but I don't know to check whether my variable value is changing according to the condition.
ifAllowed: Boolean = false;
checkRoleModifierExists() {
if (this.userDetails && this.userDetails.roles) {
for (
let userRolesIndex = 0;
userRolesIndex < this.userDetails.roles.length;
userRolesIndex++
) {
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN_SUPPORT' &&
this.roleModifiers.body &&
this.roleModifiers.body.length) {
this.ifAllowed = this.ifAllowedFun();
}
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN') {
this.ifAllowed = true;
}
}
}
}
ifAllowedFun() {
let ifRole = false;
for (const roleModifier of this.roleModifiers.body) {
if (roleModifier === 'PC-ABC') {
ifRole = true;
}
}
return ifRole;
}
this is test which I tried but it's failing.
it('should check roles modifiers ', () => {
component.ifAllowed = false;
component.ngOnInit();
spyOn(component, 'checkRoleModifierExists').and.callThrough();
component.userDetails = {
roles: ''
};
component.userDetails.roles = [ 'ROLE_ADMIN_SUPPORT' ];
component.roleModifiers = {
body: [ 'PC-ABC' ]
};
component.checkRoleModifierExists();
expect(component.ifAllowed).toEqual(true);
});

How to apply a settimeout in the VUEJS script?

I am developing my first application in vuejs and in the initial data upload in the script I need to modify the data I received from a call to the database.
Since I have modified the data it returns an error in the initial load of the page and after a few seconds it loads without problem.
I am trying to wrap this function in a settimeout but it returns an error in vuejs.
How can I apply this setTimeout?
here my script
<script>
export default {
data () {
return {
step: 1,
selected: 1
}
},
components: {
},
computed:{
selectedBasket() {
return !this.$store.getters.basket ? null : this.$store.getters.basket
},
items(){
return !this.$store.getters.items ? null : this.$store.getters.items
},
setTimeout(() => {
filteredEstimation(){
this.$store.getters.estimations.map(function(estimation) {
estimation.offers.map(function(offer) {
offer.name = offer.name.split(" ").reverse().slice(1).reverse().join(" ");
if (offer.name.includes("first")) {
offer.description = "first option";
}
if (offer.name.includes("second")) {
offer.description = "second option";
}
if (offer.name.includes("third")) {
offer.description = "third option";
}
});
});
return !this.$store.getters.estimations ? null : this.$store.getters.estimations.filter( item => item.id == this.selected )[0].offers
}, 700);
},
methods: {
getItemsName(item) {
if(item == 1){
return 'bag'
} else if(item == 2){
return 'paper'
} else {
return 'pen'
}
}
}
}
</script>
You're using that function inside the computed option, that's not allowed, you should define it in the mounted hook like :
<script>
export default {
data () {
return {
step: 1,
selected: 1
}
},
components: {
},
computed:{
selectedBasket() {
return !this.$store.getters.basket ? null : this.$store.getters.basket
},
items(){
return !this.$store.getters.items ? null : this.$store.getters.items
},
},
methods: {
getItemsName(item) {
if(item == 1){
return 'bag'
} else if(item == 2){
return 'paper'
} else {
return 'pen'
}
}
},
mounted(){
setTimeout(() => {
filteredEstimation(){
this.$store.getters.estimations.map(function(estimation) {
estimation.offers.map(function(offer) {
offer.name = offer.name.split(" ").reverse().slice(1).reverse().join(" ");
if (offer.name.includes("first")) {
offer.description = "first option";
}
if (offer.name.includes("second")) {
offer.description = "second option";
}
if (offer.name.includes("third")) {
offer.description = "third option";
}
});
});
return !this.$store.getters.estimations ? null : this.$store.getters.estimations.filter( item => item.id == this.selected )[0].offers
}, 700);
}
}
</script>

Break Nested some or map JavaScript

PC = {a:{ID: "abc",options:{x1:"100", x2:"200"}},b:{ID: "d",options:{x2:"100", x3:"200"}}}
pro = {
"pro": [
{
"pID": "abc",
"attributes": {
"xyz": [
"1",
"2",
"3"
],
"foo": "フルプレミアム"
}
}
]
}
functionX() {
let isND = true;
if (pro === null || pro === [] || pro.length === 0) {
return isND;
} else if (pro.length > 0) {
some(PC, (p) => {
some(p.options, (o, k) => {
some(pro, (item) => {
if (p.ID === item.pID && k === 'xyz') {
if (item.attributes[k] !== []) {
isND = false;
}
} else if (p.ID === item.pID && k !== 'xyz') {
if (item.attributes[k] !== '') {
isND = false;
}
}
});
});
});
}
return isND;
}
I have to iterate through 3 different collections to check my condition and return a value. I am trying to exit the nested some or map if one of my if- else conditions satisfy. I tried passing return true after isND = false but doesn't work. Can someone help resolve this.
Array.prototype.some() will exit early if any of the callbacks return true so you could return the result that way.
It's not very clear but it seems you want to use this "early exit" feature while returning the inverse. How about something like this...
// ignoring "if (pro === null || pro === [] || pro.length === 0)" for this example
// return the inverse
return !Object.values(PC).some(({ ID, options }) => {
return Object.entries(options).some(([k, o]) => {
// here "k" is one of your "x1", "x2", etc keys
// and "o" is the corresponding value
return pro.pro.some(item => {
// return "true" if any of your "conditions" are met
})
})
})
return Object.values(PC).some(({ ID, options }) => {
return Object.entries(options).some(([k]) => {
return (pro.pro).some((item) => {
if (condition) {
if (condition) {
return false;
}
return true;
} else if (condition) {
if (condition) {
return false;
}
return true;
}
return null;
});
});
});
// Haven't returned the inverse of outer function

JS find key value pair in encapsulated object

I have a big problem and I need your help.
I have a object like this:
{
folder1: {
folderid: 1,
files: {
name: "yeah.txt"
},
folder2: {
folderid: 2
folder3: {
folderid: 3
}
}
},
folder4: {
folderid: 4
}
}
and I want to search for the key "folderid = 3" and find the object.
How can I do this in JavaScript?
Kind regards and thanks for your help
I came to a more generalised solution, that supports multiple properties check:
function search(obj, properties){
if(Object.keys(properties).every(function(key){
return obj[key] === properties[key];
})) {
return obj;
} else {
Object.keys(obj).forEach(function(key){
var child = obj[key];
if(child !== null && typeof child === 'object'){
return search(child, properties);
}
});
return false;
}
}
demo: http://jsfiddle.net/dzs1orbw/
You can use a DSF algorithm to do this: http://jsfiddle.net/L5b07bt6/
var obj = {
folder1: {
folderid: 1,
files: {
name: "yeah.txt"
},
folder2: {
folderid: 2,
folder3: {
folderid: 3,
caption: "I got it!"
}
}
},
folder4: {
folderid: 4
}
};
function find(root, id) {
if (root.folderid == id) return root;
if (typeof root !== 'object') return null;
var key, val;
for (key in root) {
val = find(root[key], id);
if (val != null) return val;
}
return null;
}
var result = find(obj, 3);
if (!result) alert("Not found!");
else alert("Found: " + result.caption);
and here another one:
function findByKey (object, searchKey){
if(typeof object !== 'object'){
return false;
}
for(var key in object){
if(object[key] === searchKey){
return object;
} else {
if(typeof (object[key] === 'object')){
var result = findByKey(object[key], searchKey);
if(result){
return result;
}
}
}
}
}
http://jsfiddle.net/mattposch/ebmd8xtk/

Categories

Resources