I'm working on a very simple project that uses google books API and I have a problem. I want to save all search history in an object in database and all works fine when I'm logged in my account and all history records to a base, but when random user want to find some books I have this error:
How I can fix this?
My code:
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-grid_align-center">
<template for:each={Books} for:item='Book'>
<lightning-layout-item class="slds-m-around_xx-small slds-size_3-of-12 slds-box" key={Book.id} data-id={Book.id}>
<h2 class="slds-text-align_center"><b>{Book.volumeInfo.title}</b></h2>
<p class="slds-text-align_center">{Book.volumeInfo.authors}</p>
<img class="slds-align_absolute-center" src="">
<a target="_blank" rel="noopener noreferrer" href="" class="slds-align_absolute-center slds-m-around_x-small">
<button class="slds-button slds-button_success">Go to shop</button>
</a>
</lightning-layout-item>
</template>
</lightning-layout>
</div>
</article>
</lightning-card>
</template>
searchList.js
import { LightningElement, track } from 'lwc';
import addBookRecord from '@salesforce/apex/searchListController.addBookRecord';
export default class BooksSearch extends LightningElement {
@track Books;
searchTitleValue = '';
searchAuthorValue = '';
async findBooks()
{
if(this.searchTitleValue !== '')
{
addBookRecord({title: this.searchTitleValue, author: this.searchAuthorValue});
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=[myKey]'
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;
let shopLink;
if(this.Books[i].saleInfo.saleability == "FOR_SALE"){
shopLink = this.Books[i].saleInfo.buyLink;
} else {
shopLink = this.Books[i].volumeInfo.canonicalVolumeLink;
}
if(this.Books[i].volumeInfo.hasOwnProperty('imageLinks')) {
bookImage = this.Books[i].volumeInfo.imageLinks.thumbnail;
} else {
bookImage = 'https://i.postimg.cc/RZ3rrN0Y/noBook.png'
}
//let bookId = this.Books[i].id;
this.template.querySelector('[data-id="' + this.Books[i].id + '"]').querySelector("a").setAttribute("href", shopLink);
this.template.querySelector('[data-id="' + this.Books[i].id + '"]').querySelector("img").setAttribute("src", bookImage);
//element.setAttribute("src", bookImage);
}
} , 500);
}
updateSearchTitleValue(event)
{
this.searchTitleValue = event.target.value;
}
updateSearchAuthorValue(event)
{
this.searchAuthorValue = event.target.value;
}
}
meta file
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
<target>lightningCommunity__Page</target>
</targets>
</LightningComponentBundle>
And my Apex class
public without sharing class searchListController {
@AuraEnabled
public static void addBookRecord(String title, String author){
if(String.isNotBlank(title) && author != null)
{
book_query__c newQuery = new book_query__c();
newQuery.title_query__c = title;
newQuery.author_query__c = author;
newQuery.title_and_author__c = title + author;
upsert newQuery title_and_author__c;
}
}
}
meta
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<status>Active</status>
</ApexClass>