Search code examples
javascriptjquery-selectors

querySelector() find only two items and then fail


I'm writing a very simple website using salesForce and lwc. I want to get https request to google books API and then show result to a list.

When I want to load images for books I use querySelector() to find my tag by data-id (I set data-id from requested book ids). I use a function to iterate by Ids and then set images (I also tried to set images by this way: <img src={Book.id}> but it doesn't work.

searchList.html

<template>
    <lightning-card>
        <article class="slds-card">
            <div class="slds-card__header slds-grid">
                <header class="slds-media slds-media_center slds-has-flexi-truncate">
                    <div class="slds-media__body">
                      <h2 class="slds-card__header-title">
                          <span class="slds-text-heading_small slds-truncate slds-align_absolute-center">Books</span>
                      </h2>
                    </div>
                </header>
            </div>
            <div class="slds-card__body slds-card__body_inner">
                <div class="slds-m-bottom_x-small slds-wrap slds-grid slds-gutters">
                    <lightning-input type="text"
                        value={searchTitleValue}
                        label="Book title"
                        onchange={updateSearchTitleValue}
                        class="slds-col"
                    ></lightning-input>
                    <lightning-input type="text"
                        value={searchAuthorValue}
                        label="Author"
                        onchange={updateSearchAuthorValue}
                        class="slds-col"
                    ></lightning-input>
                </div>
                <button class="slds-button slds-button_brand slds-button_stretch" onclick={findBooks}>Find Book(s)</button>
                <lightning-layout class="slds-p-around_xx-small slds-grid slds-grid_pull-padded slds-wrap slds-box slds-grid_align-center">
                    <template for:each={Books} for:item='Book'>
                            <lightning-layout-item class="slds-m-around_xx-small slds-size_4-of-12 slds-box" key={Book.id}>
                                <h2 class="slds-text-align_center"><b>{Book.volumeInfo.title}</b></h2>
                                <p class="slds-p-horizontal_small">Author: {Book.volumeInfo.authors}</p>
                                <img data-id={Book.id} src="">
                            </lightning-layout-item>
                    </template>
                </lightning-layout> 
            </div>
        </article>
    </lightning-card>
</template>

searchList.js:

import { LightningElement, track } from 'lwc';
export default class BooksSearch extends LightningElement {
    
    @track Books;
    searchTitleValue = '';
    searchAuthorValue = '';

    async findBooks()
    {
        if(this.searchTitleValue !== '')
        {
            let tempTitle = this.searchTitleValue.replace(/ /g, '_');
            let tempAuthor = '';
            if(this.searchAuthorValue !== '')
            {
                let tempList = this.searchAuthorValue.split(' ');
                tempAuthor = '+inauthor:' + tempList[tempList.length - 1];
            }
            let url = 'https://www.googleapis.com/books/v1/volumes?q=' + tempTitle + tempAuthor +'&maxResults=40&key=[my key]'
            let fetchResult = await fetch(url);
            let jsonString = await fetchResult.json();
            this.Books = jsonString.items;
            console.log(jsonString);
        }
        setTimeout(() => {
            let size = this.Books.length;
            for(let i = 0; i < size; i++)
            {
                let bookImage = this.Books[i].volumeInfo.imageLinks.smallThumbnail;
                let bookId = this.Books[i].id;
                console.log('Current (' + i + ') book id: ' + bookId);
                let element = this.template.querySelector('[data-id=' + bookId + ']');
                console.log('Element by id: ' + element);
                element.setAttribute("src", bookImage);
            }
        } , 1000);
    }

    updateSearchTitleValue(event)
    {
        this.searchTitleValue = event.target.value;
    }

    updateSearchAuthorValue(event)
    {
        this.searchAuthorValue = event.target.value;
    }
}

So, when I load books, only two books loads and the script doesn't work, but data-id from .js and from html coincide:

enter image description here

Also when I looking for another book it load different count of images, sometimes load all images.

What I need to do to get this element by this data-id.


Solution

  • I found the problem. I forgot to paste "" in querySelector , so the correct code looks like this:

    let element = this.template.querySelector('[data-id="' + bookId + '"]');