I'm trying to create multiple lightning data tables containing book records, organized by published date. The books in each table will have the same published date.
I am having an issue converting the returned map from apex into a usable object so that i can populate the data table.
I'm looking for help, and/or suggestions on how i can better convert the Apex map into a Javascript object, and then ultimately fill the tables with records. I'll leave notes in my code and towards the end of what I tried and what I am trying to achieve
getBooks.apxc
@AuraEnabled(cacheable=true)
public static Map<Date, List<Books__c>> getBooks(Id recordId) {
Map<Date, List<Books__c>> bookMap = new Map<Date, List<Books__c>>();
List<Books__c> books = new List<Books__c>([SELECT Name, Author__c, PublishedDate__c FROM Books__c WHERE Genre__c = :recordId ORDER BY PublishedDate__c DESC]);
for (Books__c book : books) {
if (!bookMap.containsKey(book.PublishedDate__c)) {
bookMap.put(book.PublishedDate__c,new List<Books__c>());
}
bookMap.get(book.PublishedDate__c).add(book);
}
return bookMap;
}
BookComponent.js
import { LightningElement } from 'lwc';
import GetBooks from '@salesforce/apex/BooksController.getBooks';
export default class BookComponent extends LightningElement {
@api recordId;
@api publishedDate;
mainBookObj = [];
@wire(GetBooks, { recordId: '$recordId'})
loadBooks(books) {
// I tried to reference books.data in my template iteration but I was getting a "e[Yn] is not a function" error.
// This is what I eventually got working, not sure if there is a better way?
let tempBookObj = books.data
for (var key in tempBookObj) {
let value = [];
for (var innerkey in tempBookObj[key]) {
value.push({ key: innerkey, value: tempBookObj[key][innerkey] });
}
this.mainBookObj.push({ key: key, value: value })
}
}
}
BookComponent.html
<template>
<template for:each={mainBookObj} for:item="book">
<lightning-card key={book.key}>
<lightning-accordion>
<lightning-accordion-section name={book.key} label={book.key}>
<c-book-datatable book-data={book}> </c-book-datatable>
</lightning-accordion-section>
</lightning-accordion>
</div>
</lightning-card>
</template>
</template>
BookDatatable.js (this is where im stuck)
export default class BookDatatable extends LightningElement {
@api recordId;
@track bookList = [];
@track columns = [{ Label: 'Name', fieldName: 'BookName__c'},{Label: 'Author', fieldName: 'Author__c'}];
connectedCallback() {
this.loadBooks(JSON.stringify(this.bookData));
}
loadBooks(taskObject) {
const obj = (JSON.parse(taskObject));
console.log(obj);
}
}
}
BookDatatable.html
<template>
<div style="height: 300px;">
<lightning-datatable
key-field="id"
data={bookList}
columns={columns}>
</lightning-datatable>
</div>
</template>
Each iteration of the data table in BookComponent.html will give me an object with a key of the date and an inner array of the books of the same date. Which is what I want
I'm stuck in BookDatatable.js trying to figure out how to put that object in bookList which is the array on the data table that will hold the records. I think I need to iterate into the object somehow to grab the array of records.
I almost feel as if the object created from the apex map back in BookComponent.js was done incorrectly. Any suggestions welcome