Reputation: 93
In my project, I have 2 arrays being read from Firestore.
courseList - A list of courses of which a user is enrolled in
courses - A list of all of the courses available in the project
I would like to compare these using a .map so that in my course portal, only the courses of which the user is enrolled in is rendered.
Here is what the arrays look like:
courseList:
courses
I know the arrays work, however, the .map doesn't seem to be working!
Here's my code:
const {courses} = this.state
const {courseList} = this.state
{
courses.length && courses.map (course => {
if (course.courseUrl === courseList.CourseCode) {
return (
<div className = "CourseTile" key = {course.courseName}>
<div className = "CourseTitle">
<h1> {course.courseName}</h1>
</div>
<div className = "CourseDescription">
<p> {course.courseSummary}</p>
</div>
<Link to={`/course/${course.courseUrl}/courseinformation`}> <button className = "LetsGoButton"> Take course</button> </Link>
</div>
)
}
else return null;
}
)
}
If I replace
if (course.courseUrl === courseList.CourseCode)
with
if (course.courseUrl === "websitedesign")
It renders the website design course only, So I believe there's something wrong with this line.
Any help would be appreciated.
Upvotes: 2
Views: 890
Reputation: 202638
if (course.courseUrl === courseList.CourseCode)
You can filter the courses
array by checking if each course
is included in the courseList
array, matching an URL to a courseList
element's CourseCode
property. array.prototype.some
is used to iterate the course list and check that at least one courseList
item matches. Once filtered you can map the filtered result as per normal.
const {courses} = this.state;
const {courseList} = this.state;
...
{courses
.filter(({ courseUrl }) =>
courseList.some(({ CourseCode }) => CourseCode === courseUrl)
)
.map((course) => {
return (
<div className="CourseTile" key={course.courseName}>
<div className="CourseTitle">
<h1> {course.courseName}</h1>
</div>
<div className="CourseDescription">
<p> {course.courseSummary}</p>
</div>
<Link to={`/course/${course.courseUrl}/courseinformation`}>
{" "}
<button className="LetsGoButton"> Take course</button>{" "}
</Link>
</div>
);
})}
Upvotes: 0
Reputation: 2254
You are correct in where the problem lies:
course.courseUrl === courseList.CourseCode
In this case course
is a single item from a list, with a property courseUrl
. That's fine. But courseList
is an array of items, each of which has a CourseCode
property. The Array itself does not (although, interestingly, it could).
It seems like what you are trying to do is pull the full course data (from courses) but filtered to only the ones the user has. In this case, you have to loop through one list, looking through the other list for each item. What you want is filter
(or, more powerfully, reduce
) but probably not map
.
const filteredCourses = availableCourses.filter( availableCourse => studentsCourses.some( studentsCourse => studentsCourse.id === availableCourse.id ) );
You'll notice I renamed the variables to make it clear which of the two lists is being used at each part.
The outer function filter
will return a new array containing only those items that return 'true' in the callback function.
The inner callback function some
loops through another array (the student's enrolled courses) and returns true if it finds any that match the given condition.
So in English, "Filter this list of all the courses, giving me back only the courses that have a matching ID in the list of the student's enrolled courses."
Upvotes: 2