Comments (3)
I was able to figure the solution. The differene here is that we store bookmarkItems instead of bookmarkIds as in R & N course. So if we the bookmarkClickHandler has to be updated with logic to check the id by the bookmarkicon. The full code is pasted in the end. But I have another similiar problem. The problem is that when we click the bookmark icon either in the jobList or the bookmarkList, both bookmark icons will be toggled except the bookmark icon in jobDetails. As soon as I add this statement in bookmark ClickHandler, then it will show like this without the "#" in the url if we click the bookmark icon on jobList or bookmarkList . Why?
The other problem is that because the activeJobItem doesn't have the "qulification" field, there will be an error since this data is fetched from the search not with the id.
state.activeJobItem && renderJobDetails(state.activeJobItem); // This will cause the problem.
First of all, I put the id in the image so that we can grab the jobItem id in jobDetails.
<img src="${jobItem.coverImgURL}" alt="${jobItem.id}" class="job-details__cover-img">
Then, we grab the id either from the jobList or jobDetails because both of them have bookmark icon.
import {
state,
bookmarksBtnEl,
jobDetailsEl,
jobListBookmarksEl,
jobListSearchEl,
} from "../common.js";
import renderJobDetails from "./JobDetails.js";
import renderJobList, { clickHandler } from "./JobList.js";
const bookmarkClickHandler = (event, bookmarkTag = "item") => {
if (!event.target.className.includes("bookmark")) {
return;
}
const jobItemEl = event.target.closest(`.job-item`);
const id = jobItemEl?.children[0]?.getAttribute("href") || document.querySelector(".job-details__cover-img").alt;
if (
state.bookmarkJobItems.some(
(jobItem) => jobItem.id === +id
)
) {
state.bookmarkJobItems = state.bookmarkJobItems.filter(
(jobItem) => jobItem.id !== +id
);
} else {
const jobItem = state.searchJobItems.find(
(jobItem) => jobItem.id === +id
)
state.bookmarkJobItems.push(jobItem);
}
localStorage.setItem(
"bookmarkJobItems",
JSON.stringify(state.bookmarkJobItems)
);
document
.querySelector(`.job-${bookmarkTag}__bookmark-icon`)
.classList.toggle(`job-${bookmarkTag}__bookmark-icon--bookmarked`);
renderJobList();
renderJobList("bookmarks");
// state.activeJobItem && renderJobDetails(state.activeJobItem); // This will cause the problem.
event.stopPropagation();
event.preventDefault();
};
const mouseEnterHandler = () => {
bookmarksBtnEl.classList.add("bookmarks-btn--active");
jobListBookmarksEl.classList.add("job-list--visible");
renderJobList("bookmarks");
};
const mouseLeaveHandler = () => {
bookmarksBtnEl.classList.remove("bookmarks-btn--active");
jobListBookmarksEl.classList.remove("job-list--visible");
};
bookmarksBtnEl.addEventListener("mouseenter", mouseEnterHandler);
jobListBookmarksEl.addEventListener("mouseleave", mouseLeaveHandler);
jobListBookmarksEl.addEventListener("click", (event) => {
if (event.target.classList.contains("job-item__bookmark-icon")) {
bookmarkClickHandler(event);
} else {
clickHandler(event);
}
});
jobListSearchEl.addEventListener("click", (event) => {
if (event.target.classList.contains("job-item__bookmark-icon")) {
bookmarkClickHandler(event);
} else {
clickHandler(event);
}
});
jobDetailsEl.addEventListener("click", (event) => {
bookmarkClickHandler(event, "info");
});
export default bookmarkClickHandler;
from professional-javascript-course.
The second error can be resolved by adding another state activeJobItemDetails. Now, when then there is an active jobItem, click on any bookmark icon will toggle all the bookmark icons which is good. But similar problem arises when there is no active jobItem. In that case, click on jobList bookmark icon or bookmarkLIst bookmark icon will show this.
state.activeJobItemDetails && renderJobDetails(state.activeJobItemDetails); // This will cause problem when there is no activeJobItemDetails
First, add activeJobItemDetails
// STATE
export const state = {
searchJobItems: [],
bookmarkJobItems: [],
activeJobItem:{},
activeJobItemDetails:{},
currentPage: 1,
};
JobList.js
try {
const data = await getData(`${BASE_API_URL}/jobs/${id}`);
const { jobItem } = data;
state.activeJobItemDetails = jobItem;
renderSpinner("job-details");
renderJobDetails(jobItem);
} catch (error) {
renderSpinner("job-details");
renderError(error.message);
}
Second, renderJobDetails if there is an active jobItem.
Boomark.js
import {
state,
bookmarksBtnEl,
jobDetailsEl,
jobListBookmarksEl,
jobListSearchEl,
} from "../common.js";
import renderJobDetails from "./JobDetails.js";
import renderJobList, { clickHandler } from "./JobList.js";
const bookmarkClickHandler = (event, bookmarkTag = "item") => {
if (!event.target.className.includes("bookmark")) {
return;
}
const jobItemEl = event.target.closest(`.job-item`);
const id = jobItemEl?.children[0]?.getAttribute("href") || document.querySelector(".job-details__cover-img").alt;
if (
state.bookmarkJobItems.some(
(jobItem) => jobItem.id === +id
)
) {
state.bookmarkJobItems = state.bookmarkJobItems.filter(
(jobItem) => jobItem.id !== +id
);
} else {
const jobItem = state.searchJobItems.find(
(jobItem) => jobItem.id === +id
)
state.bookmarkJobItems.push(jobItem);
}
localStorage.setItem(
"bookmarkJobItems",
JSON.stringify(state.bookmarkJobItems)
);
document
.querySelector(`.job-${bookmarkTag}__bookmark-icon`)
.classList.toggle(`job-${bookmarkTag}__bookmark-icon--bookmarked`);
state.activeJobItemDetails && renderJobDetails(state.activeJobItemDetails); // This will cause problem when there is no activeJobItemDetails
renderJobList();
renderJobList("bookmarks");
event.stopPropagation();
event.preventDefault();
};
const mouseEnterHandler = () => {
bookmarksBtnEl.classList.add("bookmarks-btn--active");
jobListBookmarksEl.classList.add("job-list--visible");
renderJobList("bookmarks");
};
const mouseLeaveHandler = () => {
bookmarksBtnEl.classList.remove("bookmarks-btn--active");
jobListBookmarksEl.classList.remove("job-list--visible");
};
bookmarksBtnEl.addEventListener("mouseenter", mouseEnterHandler);
jobListBookmarksEl.addEventListener("mouseleave", mouseLeaveHandler);
jobListBookmarksEl.addEventListener("click", (event) => {
if (event.target.classList.contains("job-item__bookmark-icon")) {
bookmarkClickHandler(event);
} else {
clickHandler(event);
}
});
jobListSearchEl.addEventListener("click", (event) => {
if (event.target.classList.contains("job-item__bookmark-icon")) {
bookmarkClickHandler(event);
} else {
clickHandler(event);
}
});
jobDetailsEl.addEventListener("click", (event) => {
bookmarkClickHandler(event, "info");
});
export default bookmarkClickHandler;
from professional-javascript-course.
I found the root cause, it is because an empty object is not falsy. To check the empty object we can use JSON.stringify(state.activeJobItemDetails) !== '{}' && renderJobDetails(state.activeJobItemDetails);
from professional-javascript-course.
Related Issues (8)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from professional-javascript-course.