#rxjs #redux-observable
Вопрос:
Я очень новичок в RxJS и до сих пор использовал только Redux ( Thunk), поэтому я пытаюсь понять, как все работает вместе. В настоящее время я пытаюсь извлечь пользователя из источника (файл json) с данными, представленными в форме входа.
authEpic.js
import users from '../api/users.json';
const source = of(users);
export const authEpic = (action$) => action$.pipe(
ofType("AUTH_LOGIN_REQUEST"),
switchMap(({ authData }) => source.pipe(
find(user => authData.email === user.email amp;amp; authData.password === user.password),
map(user => ({ type: "RESULTS", results: user }))
))
);
Но ничего не возвращается, даже если в нем указано значение, возвращаемое в качестве свойств. Я хотел бы понять, как найти пользователя и передать его другому действию, так как на данный момент я почти ничего не понимаю, несмотря на то, что смотрю здесь и там.
Большое вам спасибо за вашу помощь!
Ответ №1:
Проблема в том, что of(users)
выдает одно значение: что бы это ни users
было, предположительно массив. Таким образом, внутри вашего find()
параметра user
на самом деле полный users
, а не отдельный пользователь, таким образом users.email === undefined
. find()
Оператор действует аналогично массиву find()
в том смысле, что он всегда будет возвращать (излучать) одно значение, поэтому, если ничего не найдено, возвращаемое (излучаемое) значение является буквально значением undefined
. Вот что здесь происходит. Вы излучаете действие { type: 'RESULTS', results: undefined }
Если users
это действительно массив, вы, вероятно, захотите использовать from(users)
его так, чтобы каждый пользователь излучался наблюдаемым один за другим. Тогда это работает так, как я полагаю, вы ожидаете. Вот демонстрационная версия: https://stackblitz.com/edit/redux-observable-playground-rararm?file=index.js
Если это закончится как производственный код, вы захотите обработать случай, когда совпадение с пользователем не найдено.
В стороне, я полагаю, что это не производственный код (все пароли в открытом тексте в виде файла json локально), но для тех, кто читает это, все же было бы полезно отметить, что в данном конкретном случае, вероятно, было бы более понятно просто использовать массив вместо наблюдаемого:
export const authEpic = (action$) =>
action$.pipe(
ofType('AUTH_LOGIN_REQUEST'),
// Note this is now `map` instead of `switchMap`
map(({ authData }) => {
const user = users.find(
(user) =>
authData.email === user.email amp;amp; authData.password === user.password
);
// Some how handle no match (e.g. wrong email or password)
if (!user) {
return { type: 'NO_RESULTS' };
}
return { type: 'RESULTS', results: user };
})
);
Комментарии:
1. Большое вам спасибо за ваше подробное объяснение @jayphelps. Это определенно не производственный код, а просто какой-то игровой код для понимания RxJS.