-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
インポートページの改善 #673
インポートページの改善 #673
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます!その他のエラーも修正してもらい大助かりです!
こちらの共有不足が原因で申し訳ないのですが、いくつか現行のアーキテクチャと乖離していそうな箇所があったので見ていただけると嬉しいです
export const checkScheduleDuplicate = ( | ||
{ courseRepository }: Ports, | ||
registered?: RegisteredCourse[] | ||
) => async ( | ||
year: number, | ||
schedules: Schedule[] | ||
): Promise< | ||
boolean | UnauthorizedError | NetworkError | InternalServerError | ||
> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
先にアーキテクチャのドキュメントを共有しとくべきでした…!
registered
の引数は以下のようにずらしたほうが現行のアーキテクチャに沿っていると思うのですがいかがでしょうか。
registered
はビジネスロジックに必要な引数ですが、一方で{ courseRepository }
は DI に必要な引数です。
なので registered
は { courseRepository }
と並べるよりも year
, schedules
と並べたほうがいいなと思いました。
export const checkScheduleDuplicate = ( | |
{ courseRepository }: Ports, | |
registered?: RegisteredCourse[] | |
) => async ( | |
year: number, | |
schedules: Schedule[] | |
): Promise< | |
boolean | UnauthorizedError | NetworkError | InternalServerError | |
> => { | |
export const checkScheduleDuplicate = ( | |
{ courseRepository }: Ports, | |
) => async ( | |
year: number, | |
schedules: Schedule[], | |
registered?: RegisteredCourse[] | |
): Promise< | |
boolean | UnauthorizedError | NetworkError | InternalServerError | |
> => { |
src/ui/pages/import.vue
Outdated
selected: boolean; | ||
expanded: boolean; | ||
}; | ||
const registered = await ports.courseRepository.getRegisteredCoursesByYear( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この方法ですと UI (Presentation 層) が Repository に依存してしまっており(ports.
を介してはいるものの、courseRepository
がコードの露出しているから)、現行のアーキテクチャと乖離してしまうため、以下のように UseCase を参照するのがいいと思いました。
const registered = await ports.courseRepository.getRegisteredCoursesByYear( | |
const registered = await Usecase.getRegisteredCoursesByYear( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます!
apiを複数回呼び出さないようにする工夫はしてはいるのですが、実際には複数回呼び出されていますね。 twinte-front/src/repositories/production/CourseRepository.ts Lines 188 to 216 in 391f56a
|
(代わりに返信) をインポートすると再現しました。 Original: https://discord.com/channels/1008574300787322980/1009642761827385434/1093488235759542284 |
うーん ただ↑をクリックするだけでは再現しないな… |
すみません、 |
下記の画像は上記のURLにアクセスした時の 上記の結果を得るためのコード
|
やはり、1回目の |
result.map((course) => ({ | ||
course: courseToDisplay(course), | ||
schedules: course.schedules, | ||
selected: true, | ||
selected: !registeredSet.has(`${course.year}_${course.code}`), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UIの方で「登録済み」のような表示をしたいですね。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ですね!
ただ UI の変更は Figma や CourseCard Component などいろいろ大変そうなので、一旦はユーザの不具合解消を優先して Merge でいいかなーと思っています。
Issue にしました → #676
なるほど… とすれば API インスタンスで Promise Object を保持するみたいな方法とかもいいかもしれませんね (& かつ State にも保存) async getRegisteredCoursesByYear(
year: number
): Promise<
RegisteredCourse[] | UnauthorizedError | NetworkError | InternalServerError
> {
if (this.#years.has(year)) {
// キャッシュがある場合は、キャッシュからデータを返す
const storedCourses = this.#courses.filter(
(course) => course.year === year
);
return storedCourses;
}
// 初回の呼び出しの場合、API呼び出しの結果をPromiseで待機する
if (!this.#apiCallPromise) {
this.#apiCallPromise = this.#api.call<
ApiType.RegisteredCourse[],
RegisteredCourse[],
200,
400 | 401 | 500
>(
(client) => client.registered_courses.get({ query: { year } }),
(body) => {
const courses: RegisteredCourse[] = body.map(apiToRegisteredCourse);
this.#courses = [...this.#courses, ...courses];
this.#years.add(year);
return courses;
},
[200],
[400, 401, 500]
);
}
// 初回の呼び出しの結果を待機する
const response = await this.#apiCallPromise;
// 初回の呼び出しの結果をキャッシュする
if (response.status === "success") {
const courses: RegisteredCourse[] = response.data;
this.#courses = [...this.#courses, ...courses];
this.#years.add(year);
return courses;
} else {
throw new Error("API Error: " + response.error.message);
}
} |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
schedules: Schedule[], | ||
registered?: RegisteredCourse[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const registered = await Usecase.getRegisteredCoursesByYear(ports)(year.value);
上記の箇所でrepositoryに授業が保存されるのでregistered
はなくても大丈夫だと思います。
ただ、この方法は綺麗ではないので将来的には以下の方法がいいかなと思っています。
checkScheduleDuplicate
を複数の授業に対応させる- もしくは、repositoryでapiの呼び出しの記録を持っておいて、同様のapiを複数回呼び出そうとしたときに初回のapiの結果が帰っているまで
await
して、初回のapiの結果が帰ってきたら、それを返す。 <- 上記の細川くんのやつです
registered-courses
を呼んでいたので,1 回だけ呼ぶように修正