Как фильтровать данные в двух разных состояниях, когда обещание.все решено?

#javascript #reactjs #react-native #promise #es6-promise

#javascript #reactjs #react-native #обещание #es6-обещание

Вопрос:

Я отправляю два запроса, чтобы получить

1- мои службы 2- службы администратора

когда я получил ответ, я установил состояние «MyService, admin».

теперь администрируйте сервисы, содержащие мои сервисы. Итак, я хочу отфильтровать, удаляют ли мои службы в службе администратора службу администратора из массива.

итак, я пытаюсь использовать new Set , но не работает, может быть, я что-то пропустил

и еще одна проблема, которую я использую Promise.all для ожидания двух запросов, но когда я регистрирую там состояние, я получаю начальное состояние «пустое»

образец данных «мои службы и администратор»

 [
//my service
  {
    "id": 1,
    "img": ".....",
    "name": "service 1"
  },
  {
    "id": 2,
    "img": ".....",
    "name": "service 2"
  },

  {
    "id": 3,
    "img": ".....",
    "name": "service 3"
  },
//admin service
  {
    "id": 1,
    "img": ".....",
    "name": "service 1"
  },
]
  

Фрагмент кода

   const [myServices, setMyServices] = useState([]);
  const [adminServices, setAdminServices] = useState([]);
  const [allService, setAllService] = useState([]);

  useEffect(() => {
    const getAdminServices = async () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      Api.post('/admin/service', {}, {headers})
        .then((res) => {
          let {services} = res.data;
          let serviceModified = [];
          services.map((service) => {
            serviceModified.push({
              id: service.id,
              name: service.service_name,
              img: DOMAIN_URL   service.images_show[0]?.image,
            });
          });
          console.log('admin', serviceModified);
          setAdminServices(serviceModified);
        })
        .catch((err) => console.log('err', err));
    };

    const getMyServices = async () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      Api.post('/vendor/service', {}, {headers})
        .then((res) => {
          let {services} = res.data;
          let serviceModified = [];
          services.map((service) => {
            serviceModified.push({
              id: service.id,
              name: service.service_name,
              img: DOMAIN_URL   service.images_show[0]?.image,
            });
          });
          console.log('mine', serviceModified);
          setMyServices(serviceModified);
          setSelectedService(serviceModified); // for checkbox
        })
        .catch((err) => console.log('err', err));
    };

    Promise.all([getMyServices(), getAdminServices()]).then(() => {

      let allServices = [...myServices, ...adminServices]; // log empty!
      let uniq = [...new Set(allServices)];
      console.log(myServices);
      console.log('filtered', uniq);
      console.log('here i want to filter the data', allServices);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);


UI

<FlatList
       data={allService}
       keyExtractor={(item, index) => String(index)}
       renderItem={renderMyServices}
   />
  

Комментарии:

1. Объявите let serviceModified = []; и let serviceModified = []; перед этой строкой const getAdminServices = async () => { , это может вам помочь

2. @EhsanNazeri к сожалению, нет! он по-прежнему возвращает пустой

Ответ №1:

Прежде всего, вы должны вернуть обещания из getMyServices и getAdminServices .

Кроме того, настройка состояния в react является асинхронной. Таким образом, обновления myServices и adminServices не гарантированно будут отражены к моменту, когда вы попытаетесь их использовать. Я предлагаю вам вернуть результаты из обещаний и использовать эти значения вместо состояния.

Пример:

   const [myServices, setMyServices] = useState([]);
  const [adminServices, setAdminServices] = useState([]);
  const [allService, setAllService] = useState([]);

  useEffect(() => {
    const getAdminServices = () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      return Api.post('/admin/service', {}, {headers})
        .then((res) => {
          let {services} = res.data;
          let serviceModified = [];
          services.map((service) => {
            serviceModified.push({
              id: service.id,
              name: service.service_name,
              img: DOMAIN_URL   service.images_show[0]?.image,
            });
          });
          console.log('admin', serviceModified);
          return serviceModified;
        })
        .catch((err) => console.log('err', err));
    };

    const getMyServices = () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      return Api.post('/vendor/service', {}, {headers})
        .then((res) => {
          let {services} = res.data;
          let serviceModified = [];
          services.map((service) => {
            serviceModified.push({
              id: service.id,
              name: service.service_name,
              img: DOMAIN_URL   service.images_show[0]?.image,
            });
          });
          console.log('mine', serviceModified);
          return serviceModified;
        })
        .catch((err) => console.log('err', err));
    };

    Promise.all([getMyServices(), getAdminServices()]).then(([myServices, adminServices]) => {
      // set state and do stuff
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  

Комментарии:

1. Потрясающе! это данные журнала очень хорошо, но о моих вещах:»D, как я уже говорил, Set работает не так, как ожидалось, можете ли вы, пожалуйста, проверить это?

2. Эй, еще раз, когда return Api.post(...) это означает, что здесь возвращается обещание? и когда возвращают serviceModified данные для .then ввода? и зачем тогда получать данные в массиве ([myServices, adminServices])

3. Да, он возвращает обещание. Да, когда вы возвращаете serviceModified это для then . Это массив, потому что Promise.all проходит через массив. Разрушение массива

Ответ №2:

Я думаю, вы используете promises.all неправильно.

В идеале promises.all может ожидать, только если все функции возвращают вам обещания, но в вашем случае вы возвращаетесь undefined .

Следовательно, даже до ответа на вызов API Promises.all завершит выполнение и then также будет выполнен.

вы можете реструктурировать свой код примерно так, как показано ниже (тем не менее, я вижу много возможностей для рефакторинга).

 
  const [myServices, setMyServices] = useState([]);
  const [adminServices, setAdminServices] = useState([]);
  const [allService, setAllService] = useState([]);

  useEffect(() => {
    const getAdminServices = async () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      return Api.post('/admin/service', {}, {headers});
    };

    const setMyServices = (res) => {
       let {services} = res.data;
       let serviceModified = [];
       services.map((service) => {
       serviceModified.push({
           id: service.id,
           name: service.service_name,
           img: DOMAIN_URL   service.images_show[0]?.image,
          });
       });
       console.log('mine', serviceModified);
       setMyServices(serviceModified);
       setSelectedService(serviceModified); // for checkbox
       return serviceModified;
    }
    
    const setAdminServices = (res) => {
       let {services} = res.data;
       let serviceModified = [];
       services.map((service) => {
            serviceModified.push({
              id: service.id,
              name: service.service_name,
              img: DOMAIN_URL   service.images_show[0]?.image,
            });
          });
          console.log('admin', serviceModified);
          setAdminServices(serviceModified);
       return serviceModified;
     }  


    const getMyServices = async () => {
      let AuthStr = `Bearer ${token}`;
      const headers = {
        Authorization: AuthStr,
        Accept: 'application/json',
      };
      return Api.post('/vendor/service', {}, {headers});
    };

    Promise.all([getMyServices(), getAdminServices()]).then((data) => {
      console.log(data); // will have [myServiceResponse, adminServiceReponse];
      const myServices = setMyServices(data[0]);
      const adminServices = setAdminServices(data[1]);
      let allServices = [...myServices, ...adminServices]; // log empty!
      // set doesn't work this way, use `uniq` utility function from `lodash` or develop a custom one if required.
      let uniq = [...new Set(allServices)];
      console.log(myServices);
      console.log('filtered', uniq);
      console.log('here i want to filter the data', allServices);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  

Комментарии:

1. Спасибо за ответ, но @L Lawliet Ответьте, что это немного просто / мини 🙂