Функция внутри объекта не возвращает значение - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь написать какой-нибудь код, который работает над массивом lessons внутри объекта ниже и вернуть процент выполненных уроков (отмеченных как completed: true).

Когда я console.log результат, который он просто показывает как [Function completion], а не число, как ожидалось. Где я ошибаюсь?

Для справки я использую JS с React Native, но это касается только JS, если я прав?

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>
            );
          })}

Я надеюсь получить целое число, которое затем могу передать как опору в компоненте для прогрессапоказатель. Буду очень признателен за любую помощь, заранее спасибо!

Ответы [ 3 ]

1 голос
/ 07 октября 2019

Повторять completion - это плохой знак - смешивать данные и общую реализацию и так далее. Подумайте над тем, чтобы придать вашим объектам тип (назовите его тем, что он на самом деле представляет, например Course, а не 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));

Затем вы используете его с fill={cat.getCompletion()}. Поскольку это функция, ее нужно вызывать.

(Кроме того, вам действительно нужно lessonCount, учитывая, что она выглядит как lessons.length?)

Другой вариант, который имеет смыслне требующий, чтобы эта функция была методом:

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"
/>
0 голосов
/ 07 октября 2019

Как @David Koe сказал, что вам нужно return. Однако вы передаете ссылку на функцию вместо ее вызова - попробуйте let currentCompletion = cat.completion(); в Workouts.js, и если весь ваш код работает так, как вы ожидаете, он должен вернуть результат.

0 голосов
/ 07 октября 2019

когда вы вызываете завершение, вы можете захотеть вернуть результат.

completion: function() {
      return this.findCompletion();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...