Reputation: 128
I'm attempting to write some code that runs over an array of lessons
within the object below and return the percentage of completed lessons (ones marked as completed: true
).
When I console.log
the outcome it just shows as [Function completion]
, rather than a number as expected. Where am I going wrong?
For reference I'm using JS with React Native, but this should only concern JS if I'm correct?
WorkoutCategoryData.js
export default [
{
title: "Title 1",
subtitle: "Subtitle 1",
lessonCount: 4,
lessons: [
{
title: "Lesson Name 1",
completed: true
},
{
title: "Lesson Name 2",
completed: true
},
{
title: "Lesson Name 3",
completed: false
},
{
title: "Lesson Name 4",
completed: false
},
],
completion: function() {
this.findCompletion();
}
},
{
title: "Title 2",
subtitle: "Subtitle 2",
lessonCount: 3,
lessons: [
{
title: "Lesson Name 5",
completed: true
},
{
title: "Lesson Name 6",
completed: true
},
{
title: "Lesson Name 7",
completed: true
}
],
completion: function() {
this.findCompletion();
}
}
];
function findCompletion(lessons) {
let lessonCompletion = 1;
let completedLessons = lessons.filter(lesson => lesson.completed === true)
.length;
let totalLessons = lessons.length;
lessonCompletion = (completedLessons / totalLessons) * 100;
return lessonCompletion;
}
Workouts.js
import WorkoutCategoryData from "./data/WorkoutCategoryData";
{WorkoutCategoryData.map(cat => {
let currentCompletion = cat.completion;
console.log(currentCompletion);
return (
<View style={styles.workoutContainer} key={cat.title}>
<View style={styles.workoutProgress}>
<AnimatedCircularProgress
size={50}
width={5}
rotation={0}
fill={cat.completion}
tintColor={Colors.primary}
backgroundColor="#dddddd"
/>
</View>
<View style={styles.workoutText}>
<Text style={styles.workoutTitle}>{cat.title}</Text>
{cat.subtitle ? (
<Text style={styles.workoutSubtitle}>{cat.subtitle}</Text>
) : null}
</View>
</View>
);
})}
I'm hoping to get an Integer number I can then pass in as a prop in a component for a progress indicator. Any help would be very much appreciated, thanks in advance!
Upvotes: 0
Views: 119
Reputation: 2376
Like @David Koe said you need to return
. However you are passing a reference to the function instead of invoking it - Please try let currentCompletion = cat.completion();
in Workouts.js and if the rest of your code is working as you expect it should return the result.
Upvotes: 0
Reputation: 225074
Repeating completion
like that is a bad sign – mixing data and common implementation and so on. Consider giving your objects a type (name it what it actually represents, like Course
, not Thing
):
class Thing {
constructor(data) {
this.title = data.title;
this.subtitle = data.subtitle;
this.lessonCount = data.lessonCount;
this.lessons = data.lessons;
}
getCompletion() {
let completedLessons = this.lessons.filter(lesson => lesson.completed).length;
let totalLessons = this.lessons.length;
return (completedLessons / totalLessons) * 100;
}
}
export default [
{
title: "Title 1",
subtitle: "Subtitle 1",
lessonCount: 4,
lessons: [
{
title: "Lesson Name 1",
completed: true
},
{
title: "Lesson Name 2",
completed: true
},
{
title: "Lesson Name 3",
completed: false
},
{
title: "Lesson Name 4",
completed: false
},
],
},
{
title: "Title 2",
subtitle: "Subtitle 2",
lessonCount: 3,
lessons: [
{
title: "Lesson Name 5",
completed: true
},
{
title: "Lesson Name 6",
completed: true
},
{
title: "Lesson Name 7",
completed: true
},
],
},
].map(data => new Thing(data));
Then you use it with fill={cat.getCompletion()}
. Since it’s a function, it needs to be called.
(Also, do you really need lessonCount
, considering it appears to be lessons.length
?)
Another option that makes sense is not requiring this function to be a method:
let getCompletion = ({lessons}) => {
let completedLessons = lessons.filter(lesson => lesson.completed).length;
let totalLessons = lessons.length;
return (completedLessons / totalLessons) * 100;
};
<AnimatedCircularProgress
size={50}
width={5}
rotation={0}
fill={getCompletion(cat)}
tintColor={Colors.primary}
backgroundColor="#dddddd"
/>
Upvotes: 1
Reputation: 342
when you call completion, you might want to return the result.
completion: function() {
return this.findCompletion();
}
Upvotes: 0