1

I had a solution where the filtering of item tags worked. Updated so the books could receive multiple tags and added the tag array:

const bookListBefore = [
  { id: 1, tag: 'Fysik' },
  { id: 2, tag: 'Marketing' },
  { id: 3, tag: '' },
  ];

 const bookListNow = [
 { id: 1, tag: ['Fysik', 'Matematik'] },
 { id: 2, tag: ['Analytics', 'Marketing', 'Data'] },
 { id: 3, tag: [''] },
 ];

Now I am struggling on finding a solution to filter those items that have a specific tag. Before with the single tags I could perform a filter and could display items with specific tags with this solution:

const filteredList = bookList
    .filter(item => (item.title.toLowerCase().includes(searchTextHome)
      || item.author.toLowerCase().includes(searchTextHome))
      && (selectedTags.length > 0 ? selectedTags.includes(item.tag) : true));

 <section className={stylesSCSS.bookContainer}>
        {filteredList.length === 0 ? emptyPlaceholder()
          : filteredList.map(item => (
            <BookItem
              cover={item.cover}
              item={item}
              userTagData={userTagData}
              onTagSelected={onTagSelected}
            />
          ))
        }
  </section>

The first part of the "search" filtering the bookList is about an input search field but this second part (selectedTags.length > 0 ? selectedTags.includes(item.tag) : true) Is where I am not able to filter the tag array, and have no ideas on how to use maybe spread operator or array functions to filter the tag arrays. Any ideas?

2
  • can you show how selectedTags looks like ? is it an array or string ? Commented Aug 22, 2019 at 18:01
  • selectedTags is an array of strings. @Code Maniac Commented Aug 22, 2019 at 18:11

2 Answers 2

1

I think it will work with the array function some

selectedTags.length > 0 ? selectedTags.some(st => item.tag.includes(st)) : true

With this at least one selected tag should match the list of book tags and it will be displayed.

Sign up to request clarification or add additional context in comments.

Comments

1

You are passing an array to includes. includes takes two arguments the first one is a value to check and the second is the position in the array (optional)

[1,2,3].includes(1) //true
[1,2,3].includes(1,3) //false

You need to check each element from tag at a time

const { tag } = book

for(let item of tag){
    if(list.includes(item)) return true
}
return false

Your code should look like this

const filteredList = bookList.filter(item => 
    (item.title.toLowerCase().includes(searchTextHome)
    || item.author.toLowerCase().includes(searchTextHome))

const result = selectedTags.length > 0 ? filteredList.filter(x =>{
    const { tag } = x

    for(let item of tag) {
        if(selectedTags.includes(item)) return true
    }
    return false
}) : filteredList

1 Comment

Thank you for showing how it works. Some interesting things in your solution @Dupocas

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.