Redux-Наблюдаемый : функция find() ничего не возвращает

#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.