I'm creating a library archive site containing a collection of my favorite reads. I have a click event listener on the books, adding them to my local storage key 'books' when doing so. I want it so that, if I click on the same book twice, it won't be added as a duplicate value in my ls. I've tried things I've found on here like an "if" statement checking the index of the new 'book' and comparing it to others, as well as filtering, but to no avail.
document.querySelectorAll('.card').forEach(function(uibook){
let arr = []
for(i=0;i < uibook.length; i++){
arr.push(uibook[i])
console.log(arr)
return arr
}
uibook.addEventListener('click',function(){
window.document.location = './details.html'
const title = uibook.innerText
const summary = uibook.querySelector('.card-summary').innerText
const genre = uibook.querySelector('.card-genre').innerText
const author = uibook.querySelector('.card-author').innerText
const page = uibook.querySelector('.card-page').innerText
const img = uibook.querySelector('img.card-img-top').getAttribute('src');
// Instantiate book
const Nbook = new book(title,genre,author,page,summary,img);
console.log(Nbook)
if (localStorage.getItem('books') === null){
books = [];
}
else{
books = JSON.parse(localStorage.getItem('books'));
}
books.push(Nbook)
localStorage.setItem('books', JSON.stringify(books));
// localStorage.clear();
add('lastKey',Nbook)
})
})
var lastKey;
function add(key,value) {
lastKey = key;
console.log(value)
localStorage.setItem(lastKey, JSON.stringify(value));
}
////////////////DETAILS PAGE/////////////////////////
function getBooks(){
// let lastKey;
if(localStorage.getItem('lastKey') === null){
lastKey = [];
} else {
lastKey = JSON.parse(localStorage.getItem('lastKey'));
}
console.log(lastKey)
//details info UI
document.querySelector('.details-title').innerText = `${lastKey.title}`
var imgTest = document.querySelector('.details-img').src = `${lastKey.img}`
console.log(imgTest)
document.querySelector('.summary-text').innerText = `${lastKey.summary}`
document.querySelector('.genre-text').innerText = `${lastKey.genre}`
console.log(document.querySelector('.author-text').innerText = `${lastKey.author}`)
document.querySelector('.pageNum-text').innerText = `${lastKey.page}`
}
getBooks()
Edit: updated the code I should also add that I have 2 keys in my ls. One is the 'lastkey', which as you may have guessed just has the value of the last book that was clicked on. This is to output the details of the book on the following page. The 'book' key is to have all of the books that I click on w/o duplicates. The purpose is b/c I have a carousel at the bottom of the page where I want to output suggested books by their genre, and I don't want to have duplicates of the same books. knowwhatimean?
To make comparison easy, you could have the books array be an array of JSON strings that you can compare with === or .includes:
if (localStorage.getItem('books') === null) {
books = [];
} else {
books = JSON.parse(localStorage.getItem('books'));
}
const stringified = JSON.stringify(Nbook);
if (!books.includes(stringified)) {
books.push(stringified);
}
localStorage.setItem('books', JSON.stringify(books));
Then, when parsing books elsewhere, call JSON.parse on array items to get to the underlying object, eg
const books = JSON.parse(localStorage.getItem('books')).map(JSON.parse);
// console.log(book[0].title)
Search your books array for another book with the same title.
uibook.addEventListener('click', function() {
window.document.location = './details.html'
const title = uibook.innerText
if (localStorage.getItem('books') === null) {
books = [];
} else {
books = JSON.parse(localStorage.getItem('books'));
}
const foundBook = books.find(book => book.title == title);
if (!foundBook) {
// Instantiate book
const summary = uibook.querySelector('.card-summary').innerText
const genre = uibook.querySelector('.card-genre').innerText
const author = uibook.querySelector('.card-author').innerText
const page = uibook.querySelector('.card-page').innerText
const img = uibook.querySelector('img.card-img-top').getAttribute('src');
const Nbook = new book(title, genre, author, page, summary, img);
books.push(Nbook);
console.log(Nbook)
localStorage.setItem('books', JSON.stringify(books));
add('lastKey', Nbook)
} else {
add('lastKey', foundBook);
}
})
Related
i know that the problem is that let todoList is an empty array, but i dont know how to solve it.
the id tags in my created html is so e can create a delete button later
heres my code:
const textArea = document.querySelector("textarea");
const button = document.querySelector("button");
const listContainer = document.querySelector(".list-container");
let id = 0;
let todoList = [];
button.onclick = function () {
const listItem = {
title: textArea.value,
};
todoList.push(listItem);
addToStorage(todoList);
const dataFromStorage = getFromStorage();
createHtml(dataFromStorage);
};
function addToStorage(items) {
const stringify = JSON.stringify(items);
localStorage.setItem("list", stringify);
}
function getFromStorage() {
const data = localStorage.getItem("list");
const unstrigified = JSON.parse(data);
return unstrigified;
}
const createHtml = (data) => {
id++;
listContainer.innerHTML = "";
data.forEach((item) => {
listContainer.innerHTML += `<div class="list-item" data-id=${id}><p>${item.title} </p><button class="remove" data-id=${id}>Delete</button></div>`;
});
};
The problem here is you just forgot to load the data from localStorage when the page loaded like this
window.onLoad = () => {
const dataFromStorage = getFromStorage();
if(dataFromStorage){
createHtml(dataFromStorage);
} else {
createHtml([]);
}
}
The problem in the code is as follows
Initially the todolist will be an empty array. so when you do the below
todoList.push(listItem);
// adding to local storage which will override the existing todos when page is refreshed
addToStorage(todoList);
// So when the below line is executed only the latest todo will be returned
const dataFromStorage = getFromStorage();
createHtml(dataFromStorage);
Fix:
Initialise the todos from localstorage instead of an empty array
let todoList = [];
// change it as below
let todoList = getFromStorage();
Now Modify the getFromStorage() as below
// If the data is present in the localStorage then return it, else return empty array
function getFromStorage() {
const data = localStorage.getItem("list");
if (!data) return [];
const unstrigified = JSON.parse(data);
return unstrigified;
}
Now when the page is loaded, we need to display the todos. Add the below lines of code
window.onload = function () {
createHtml(todoList);
};
That's it. This will fix the issue.
Few minor improvements can be made as well.
todoList.push(listItem);
addToStorage(todoList);
const dataFromStorage = getFromStorage(); // this line is not necessary, remove it
createHtml(dataFromStorage); // change this to createHtml(todoList)
Codepen
Thanks.
I need help from some of you experienced folks. I am attempting to generate tickets that hold metadata in JSON format. I am a fairly new developer. My idea in this is to take a user and have them create an event with x amount of tickets. The user or our company will then enter the standard input info (venue name, artist name, select seat numbers, sections etc). I want to be able to generate thousands of tickets, each with the correct info that reflects the venue. In general how should I go about this?
Below is me messing around with ways to do this, but I don't have a lot of experience as you can see. I was able to get the tickets to put in String info, but not have seat numbers iterate and increase etc.
import { watchFile, writeFile } from "fs";
import fs from "fs";
class BlockPass_`enter code here`PermanentData {
constructor(venue_Name, artist_Name, genre) {
this.venue_Name = venue_Name;
this.artist_Name = artist_Name;
this.genre = genre;
}
}
let ticket_Omega = new BlockPass_PermanentData(
"Catalyst",
"As I Lay Dying",
"Post-Hardcore Metal"
);
const maxTickets = 10;
function makeTickets(maxTickets) {
const tickets = {};
for (let i = 0; i < maxTickets; i++) {
tickets[i] = ticket_Omega;
}
return tickets;
}
let tickets_Generated = makeTickets(maxTickets);
const ticket_MetaData = JSON.stringify(tickets_Generated);
console.log(ticket_MetaData);
writeFile("JSON/tickets_Omega.JSON", ticket_MetaData, function (err) {
if (err) throw err;
console.log("Omega Tickets generated. Begin Modifications.");
});
The main issue with your code is that you are setting all your tickets to the same object (ticket_Omega). You probably want to generate a new object for every ticket.
I would do something like this instead:
class Event {
constructor(venue_Name, artist_Name, genre) {
this.venue_Name = venue_Name;
this.artist_Name = artist_Name;
this.genre = genre;
}
makeTickets(maxTickets) {
const tickets = {};
for (let i = 0; i < maxTickets; i++) {
tickets[i] = {
seatNumber: i,
sold: false,
venue_Name: this.venue_Name,
artist_Name: this.artist_Name,
genre: this.genre,
};
}
return tickets;
}
}
const some_event = new Event("Catalyst", "As I Lay Dying", "Post-Hardcore Metal");
let tickets = some_event.makeTickets(10);
console.log(tickets);
i'm trying to use localstorage for my array of objects but it doesn't work (without the localstorage it works perfectly). after a few days of tries i'm trying here. can anyone help please?
The Code:
<script>
var notes = JSON.parse(localstorage.getitem("notes") || "[]");
function todo() { // Gets invoked by a submit button
var list = document.getElementById("tasklist").value;
var taskdate = document.getElementById("taskdate").value;
var tasktime = document.getElementById("tasktime").value;
const note = {
list: list,
taskdate: taskdate,
tasktime: tasktime
}
notes.push(note);
for (i = 0; i < notes.length; i++) {
document.getElementById("name").append(notes[i].list);
}
localStorage.setItem("notes", JSON.stringify(notes));
}
</script>
You have used incorrect keyword.
localstorage => localStorage
getitem => getItem
Your code seems valid except for some syntax errors. Use a good IDE or code editor or whatever to show you that errors. I recommend vscode
var notes = JSON.parse(localStorage.getItem("notes") || "[]");
function todo() { // Gets invoked by a submit button
var list = document.getElementById("tasklist").value;
var taskdate = document.getElementById("taskdate").value;
var tasktime = document.getElementById("tasktime").value;
const note = {
list: list,
taskdate: taskdate,
tasktime: tasktime
};
notes.push(note);
for (let i = 0; i < notes.length; i++) {
document.getElementById("name").append(notes[i].list);
}
localStorage.setItem("notes", JSON.stringify(notes));
}
try please declare as array, note variable
var note = array();
note = {
list: list,
taskdate: taskdate,
tasktime: tasktime
}
I'm using WIX.
I have created a membersTable that is connected to my MembersListDetails dataset.
MembersListDetails dataset has a field FirstName that is a reference field from members/privateMembersData dataset.
MembersListDetails dataset also has a membersTags field dataset that is a reference field from membersTags dataset it can be filtered.
This all works, however I can't find the code to allow me to sort my membersTable by firstName.
I have found in the WIX documents that WIX can't sort a reference field. But that you can query a reference field
Code Examples:
import wixData from 'wix-data';
let options = {
"order": "asc"
};
$w.onReady(function () {
wixData.queryReferenced("members/privateMembersData", "firstName", options)
.then((results) => {
if (results.items.length > 0) {
let firstItem = results.items[0]; //see item below
} else {
// handle case where no matching items found
}
})
.catch((err) => {
let errorMsg = err;
});
});
I also tried this:
export function membersListDetails_beforeQuery(query, context) {
let hookContext = context; // see below
let newQuery = wixData.query("#membersListDetails")
.ascending("firstName", "lastName")
.find()
.then( (results) => {
if(results.items.length > 0) {
let items = results.items;
let firstItem = items[0];
let totalCount = results.totalCount;
let pageSize = results.pageSize;
let currentPage = results.currentPage;
let totalPages = results.totalPages;
let hasNext = results.hasNext();
let hasPrev = results.hasPrev();
let length = results.length;
//let query = results.query;
} else {
// handle case where no matching items found
}
} )
.catch( (error) => {
let errorMsg = error.message;
let code = error.code;
} );
return newQuery;
}
I don't get any errors but the First Name field never sorts.
Can someone please help me out!!!
Thank you!
Sylvia
I need to create a new array from iterating mongodb result. This is my code.
const result = await this.collection.find({
referenceIds: {
$in: [referenceId]
}
});
var profiles = [];
result.forEach(row => {
var profile = new HorseProfileModel(row);
profiles.push(profile);
console.log(profiles); //1st log
});
console.log(profiles); //2nd log
I can see update of profiles array in 1st log. But 2nd log print only empty array.
Why i couldn't push item to array?
Update
I think this is not related to promises. HorseProfileModel class is simply format the code.
const uuid = require("uuid");
class HorseProfileModel {
constructor(json, referenceId) {
this.id = json.id || uuid.v4();
this.referenceIds = json.referenceIds || [referenceId];
this.name = json.name;
this.nickName = json.nickName;
this.gender = json.gender;
this.yearOfBirth = json.yearOfBirth;
this.relations = json.relations;
this.location = json.location;
this.profilePicture = json.profilePicture;
this.horseCategory = json.horseCategory;
this.followers = json.followers || [];
}
}
module.exports = HorseProfileModel;
await this.collection.find(...)
that returns an array of the found data right? Nope, that would be to easy. find immeadiately returns a Cursor. Calling forEach onto that does not call the sync Array.forEach but rather Cursor.forEach which is async and weve got a race problem. The solution would be promisifying the cursor to its result:
const result = await this.collection.find(...).toArray();
Reference