angularjs some method for search data result not working - javascript

Search results are not working while entering the details.
For Example i have a value "Google Search Result".
If I search "g", "go", "goo" ... "Google Search" or "Search Result" it is working fine.
But If I search "Google Result", without entering the middle word, it is not showing anything.
How can I achieve this in angularjs,
return cardDetails.filter(function (card) {
return (!$scope.search || ($scope.search && $scope.search.toLowerCase().split(' ').every(function(str){
return card.Tag.toLowerCase().indexOf(str) != -1;
})));
}).length > 0;
$scope.getAllCards.filter Instead of using filter method, how can I use angular "Array Some method"
In this code, search is working fine. But the only thing, I need to enter continiously, if I enter first and last, it is not showing anything. Only empty result is coming.
Can anyone help me to do this?

The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
In your case you need to use every function
The every() method tests whether all elements in the array pass the
test implemented by the provided function. It returns a Boolean value
Here is the working example
const searchValue = "Google Result";
const tags = ["Google", "Google Search Result", "Another Google Result","Result of Google"];
const searchArr = searchValue.split(' ');
const filteredTags = tags.filter(item => {
// loop searchArr array and test if current item includes all occurrence
return searchArr.every(el => item.includes(el));
})
console.log(filteredTags);
For angularjs it will like this
$scope.getTags = function () {
var searchArr = $scope.search.split(' ');
return $scope.getAllCards.filter(function(item) {
return searchArr.every(function(el){
return item.includes(el);
})
}

You could use Array.prototype.reduce() to split the array and search among the it for the search text and return if it exists or not as follows:
const getAllCards = [{
Tag: 'card1',
pillarid: '1'
}, {
Tag: 'card2',
pillarid: '7'
}, {
Tag: 'Google Search Result',
pillarid: '0'
}],
categoryId = 0;
getTags = function(search) {
return getAllCards.some(function(a) {
return a.Tag;
}) ? getAllCards.filter(function(card) {
return (!search || (search && search.split(' ').reduce(function(acc, str) {
return acc && (card.Tag.toLowerCase().indexOf(str.toLowerCase()) !== -1);
}, true) && card.pillarid != '7' && (categoryId == card.pillarid || categoryId == 0)));
}) : [];
}
document.getElementById('input').addEventListener('keyup', function() {
console.clear();
console.log(getTags(this.value));
})
<input id="input" />
PS: you don't need a .map() chained to .filter() as you've put in your example

Related

Array.filter() is not working - the filter isn't executing

I am trying to filter an array of objects with 3 filters. The first two execute as expected but the last one does not execute at all. There is a lot of code in total so here is the Github link:
Github repository
function FormatSearch() {
return search.value.toLowerCase().replace("č", "c").replace("ć", "c").replace("š", "s").replace("ž", "z")
}
function FormatLocation() {
return location.value.toLowerCase().replace("č", "c").replace("ć", "c").replace("š", "s").replace("ž", "z")
}
let filtered = allPosts
//filter po imenu/opisu
.filter(post => post.title.includes(FormatSearch()) || post.description.includes(FormatSearch()))
//filter po kategoriji
.filter(post => filters.includes(post.category) || filters.length == 0)
//filter po lokaciji
.filter(post => async function(){
let owner = await post.getOwner()
return Boolean(owner.info[1].includes(FormatLocation()) || FormatLocation() == "")
})
document.getElementById("posts").innerHTML = ""
filtered.forEach(post => {
post.addPost()
})
Agree to VLAZ, you can choose return a promise array and Promise.all them or use async/await in a for loop which basically has the same speed as filter.

no exact match with indexOf

I seem to be having a problem with indexOf to get an exact match.
I have an API that searches for items in MongooseDB where the search query matches. This works only to some extend.
Here is the used code:
exports.searchItems = (req, res) => {
console.log(req.query.searchQuery);
if (!req.query || !req.query.searchQuery) {
return res.status(400).send({
message:"'searchQuery' param should be passed with valid query!"
});
}
Item.find().then(itemsList => {
if(!itemsList) {
return res.status(404).send({
message: "No Items found for search query: " + req.query.searchQuery
});
}
var items = [];
const queryVal = req.query.searchQuery;
itemsList.forEach(function(item){
if(item) {
if(JSON.stringify(item).indexOf(queryVal) > -1) {
items.push(item);
}
}
});
res.status(200).send({items});
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occured while fetching all items!"
});
});
};
Now let's say the search query is "LO_Buehne2" the result will be:
{"items":[{"_id":"5f9fcf321337250c6815ac47","ort":"LO_Buehne2","bezeichnung":"ABB Beleuchtungsstärkemessgerät","seriennummer":"H42805104","pruefdatum":"01.01.2021","ausgeliehen":false,"ausleih_datum":"","ausleih_name":"","ausleih_nummer":"","rueckgabe_datum":"","einsatzort":"","notiz":"","url":"http://192.168.1.48/fileserver/uploads/asfgasfasf.jpg","createdAt":"2020-11-02T09:19:46.287Z","updatedAt":"2021-03-19T10:41:45.591Z","__v":0}]}
This is correct since there is only one item with "ort":"LO_Buehne2"
But if I search for LO_Buehne the result will be this:
{"items":[{"_id":"5f8fe281ee35da3068b0ac49","ort":"LO_Buehne","bezeichnung":"Panasonic Akku- u. Schlagschrauber","seriennummer":"9090442 / 9080163","pruefdatum":"01.01.2021","ausgeliehen":false,"ausleih_datum":"","ausleih_name":"","ausleih_nummer":"","rueckgabe_datum":"","einsatzort":"","url":"http://192.168.0.65/fileserver/3.jpg","createdAt":"2020-10-21T07:25:53.855Z","updatedAt":"2021-03-19T10:37:17.774Z","__v":0,"notiz":""}
...
...
...
{"_id":"5f9fcf321337250c6815ac47","ort":"LO_Buehne2","bezeichnung":"ABB Beleuchtungsstärkemessgerät","seriennummer":"H42805104","pruefdatum":"01.01.2021","ausgeliehen":false,"ausleih_datum":"","ausleih_name":"","ausleih_nummer":"","rueckgabe_datum":"","einsatzort":"","notiz":"","url":"http://192.168.1.48/fileserver/uploads/asfgasfasf.jpg","createdAt":"2020-11-02T09:19:46.287Z","updatedAt":"2021-03-19T10:41:45.591Z","__v":0}
As you can see, it finds all items with "ort":"LO_Buehne" but it will also find that one item with "ort":"LO_Buehne2".
Question is...why? And how do I fix this?
If you're looking for an exact match you have two solutions.
Regex magic
Work with javascript objects and === instead of JSON strings.
1. Regex Solution
const search = 'LO_Buehne';
const reg = new RegExp(`"${search}"`);
console.log(reg.test('{opt: "LO_Buehne2"}')); // fail
console.log(reg.test('{opt: "LO_Buehne"}')); // works
This is simple regex that looks to see if the search term you're looking for is surrounded by " (double quotes). This will only work for values in double quotes.
2. Working with objects
const data = {"items":[{"_id":"5f9fcf321337250c6815ac47","ort":"LO_Buehne2","bezeichnung":"ABB Beleuchtungsstärkemessgerät","seriennummer":"H42805104","pruefdatum":"01.01.2021","ausgeliehen":false,"ausleih_datum":"","ausleih_name":"","ausleih_nummer":"","rueckgabe_datum":"","einsatzort":"","notiz":"","url":"http://192.168.1.48/fileserver/uploads/asfgasfasf.jpg","createdAt":"2020-11-02T09:19:46.287Z","updatedAt":"2021-03-19T10:41:45.591Z","__v":0},{"_id":"5f8fe281ee35da3068b0ac49","ort":"LO_Buehne","bezeichnung":"Panasonic Akku- u. Schlagschrauber","seriennummer":"9090442 / 9080163","pruefdatum":"01.01.2021","ausgeliehen":false,"ausleih_datum":"","ausleih_name":"","ausleih_nummer":"","rueckgabe_datum":"","einsatzort":"","url":"http://192.168.0.65/fileserver/3.jpg","createdAt":"2020-10-21T07:25:53.855Z","updatedAt":"2021-03-19T10:37:17.774Z","__v":0,"notiz":""}]}
const search = 'LO_Buehne';
const res = data.items.filter(item => {
return new Set(Object.values(item)).has(search);
});
console.log(res);
This solution consists in doing a strict equal to see if the value exists. In the above example I use a combination of Object#values and Set, but it's completely doable with Array#find / Array#findIndex.
i.e.:
const res = data.items.filter(item => {
return Object.values(item).findIndex(value => value === search) > -1;
});

how to filter strings in nested array?

I'm trying to implement a search function that returns find which has search word in the specified array. Let's say, a collection has [aa, ab, aaa], and search word is "a". In this case, return the object to display. Because at least one of the strings in the array has 'a'.
dataStructure
[
{
name:'aa',
searchWords:['aa','ab','bc'] <- I want to use this array for search
},
{
name:'bb',
searchWords:['bb','bc','de'] <- I want to use this array for search
},
...
]
I tried to fix the issue, by using includes(), filter(),indexOf(). However still it returns nothing or returns data when the search word is exactly matched.
How to fix the code to achieve aiming?
Thank you in advance!
this part works well
let filterStudents = students;
if (searchName.length > 0 && searchTag.length === 0) {
filterStudents = students.filter((student) => {
if (
student.firstName.toLowerCase().includes(searchName.toLowerCase())
|| student.lastName.toLowerCase().includes(searchName.toLowerCase())
) {
return true;
}
return false;
});
Problem happens on this part
} else if (searchName.length === 0 && searchTag.length > 0) {
filterStudents = students.filter(
(student) => {
console.log(student.tags);
student.tags.filter((tag) => {
console.log(tag);
tag.indexOf(searchTag) > -1;
});
},
);
} else if (searchName.length > 0 && searchTag.length > 0) {
} else {
console.log('both');
}
You don't return from the filter callbacks
As a sidenote, there is also String#includes:
filterStudents = students.filter(student =>
student.tags.some((tag) => tag.includes(searchTag))
);
If you only want to search for matches when the corresponding searchTag or searchName is filled out, use the conditional operator inside the filter callback to check whether the filter test should be carried out:
const students = [
{
name:'aa',
searchWords:['aa','ab','bc']
},
{
name:'bb',
searchWords:['bb','bc','de']
},
];
const doFilter = () => {
const [searchName, searchTag] = [...document.querySelectorAll('input')]
.map(input => input.value.toLowerCase());
const filtered = students.filter(({ name, searchWords }) => (
(searchName ? name.toLowerCase().includes(searchName) : true) &&
(searchTag ? searchWords.some(word => word.toLowerCase().includes(searchTag)) : true)
));
code.textContent = JSON.stringify(filtered);
};
window.addEventListener('change', doFilter);
<input placeholder="searchName">
<input placeholder="searchTag">
<div>
<code id="code"></code>
</div>

Find texbox value match in an array

I am trying to look for texbox values matching an array I have provided a code snippet below:
$('#message').on('keyup', function () {
suggest_array_sample = [
{ array_val: "#{person1}" },
{ array_val: "#{person2}" },
{ array_val: "#{person3}" }
];
found_variable_array = [];
$.each(suggest_array_sample, function (key, value) {
console.log(value);
if ($.inArray(value, textbox_value)) {
console.log('found');
found_variable_array.push(value);
} else {
console.log('not found');
}
})
console.log(found_variable_array);
});
<textarea id="message"></textarea>
The problem is it always return the whole array instead of just the matches the ouput should be when I type #{person1} on the textbox the output should be
[{array_val:"#{person1}"}] //expected output
[{array_val:"#{person1}"},{array_val:"#person2"}]// expected output when two or more matches are found on the textbox
instead of
[{array_val:"#{person1}"},]{array_val:"#{person2}",{array_val:"#{person3}"}] //current output
is this possible using the inArray() or do I need to change the code.
use filter method of Array.
yourArray.filter ( yourArrayModel => yourArrayModel.fieldValue === yourSearchValue )
In your case yourSearchValue can be “{#person1}”
For more information, look for filter method documentation, i hope this is what you want.
$.inArray return a position, if not found return -1 else return >= 0
The $.inArray() method is similar to JavaScript's native .indexOf()
method in that it returns -1 when it doesn't find a match. If the
first element within the array matches value, $.inArray() returns 0
Try this code
$('#message').on('keyup', function () {
textbox_value = $(this).val();
suggest_array_sample = ["#{person1}", "#{person2}", "#{person3}"];
console.log($.inArray(textbox_value, suggest_array_sample));
});
It's not entirely clear what you're trying to achieve. I've written something using $.inArray that tells you the array index of the found value. You need to use .map() on the array to extract the val you want.
EDIT:
From what I understood of your comment, I've now had the value be added to found_value_array each time the value is found.
Or is it that you want an array to be returned because the same value might appear multiple times?
let found_variable_array = [];
$('#message').on('keyup',function(){
suggest_array_sample = [
{array_val:"#{person1}"},
{array_val:"#{person2}"},
{array_val:"#{person3}"}
]
let index = $.inArray($(this).val(), suggest_array_sample.map(o => o.array_val));
if (index >= 0) found_variable_array.push(suggest_array_sample[index]);
console.log(found_variable_array);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="message"></textarea>
After combining ideas presented here this method work for me
match_value = suggest_array.filter(function(result){
if(textbox_value){
return textbox_value.search(result)>-1
}
else{
return false
}
})
console.log(match_value);

ReactJS / ES6: Searching Japanese text using includes?

So, I'm writing a client-side search and I need to look through strings of Japanese characters. I'm wondering how to do this properly?... i.e. Do I change the format of the text into utf-8 something and then search the utf-8?
Example:
All my data has japaneseData.title : "フェリーチェ三田"
When I type in my search.value as : "フェ" using japaneseData.title.includes(search.value) I don't get a match...
How do I do this correctly?
Okay, after further inspection, the comments were correct and includes was finding the substring. This is all happening inside of a filter() and I'm trying to return the objects that match...
After changing my code to:
let filteredArrayofObjects = Lists.houseLists.filter(house => house.building_name.includes(query.search));
I was getting back some but not all. Problem cases:
"アーバイルスパシエ芝浦BAY-SIDE".includes("エ芝浦"); // this evaluates to true, but does not get included in my filtered array...
Okay, further digging, it seems the issue is I need to wait for the filter process before returning the results... haven't yet found a solution to that just yet.
async filter(arr, callback) {
return (await Promise.all(
arr.map(async item => {
return (await callback(item)) ? item : undefined;
})
)).filter(i => i !== undefined);
}
handleFilterLists = async (query = {}) => {
const { Lists } = this.props;
let searchResults = await this.filter(Lists.houseLists, async house => {
return house.building_name.includes(query.search);
// the final evaluation to look similar to this:
// var newArray = homes.filter(function (el) {
// return el.price <= 1000 &&
// el.sqft >= 500 &&
// el.num_of_beds >=2 &&
// el.num_of_baths >= 2.5;
// });
});
this.setState({ searchResults });
}
Okay, so, I'm trying to set state.searchResults after the filter method has checked for matching objects in the array Lists.houseLists...
includes returns true or false if the substring is detected or not. If you want the index of where the first detected substring begins, use indexOf.
I used your sample source and search text with includes and it returns true.
Edit:
I used your updated data and this still works. https://codepen.io/anon/pen/RMWpwe
const sourceText = 'アーバイルスパシエ芝浦BAY-SIDE';
const searchText = 'エ芝浦';
const lists = [
'スパシエ',
'芝浦BAY-SIDE',
'エ芝浦',
'パシエ芝浦BAY'
];
console.log(lists.filter(item => item.includes(searchText)));
// ["エ芝浦", "パシエ芝浦BAY"]

Categories