Не могу получить объект из промиса
Моя проблема заключается в получении ответа с сервера, сервер возвращает promis через функцию
import CryptoJS from 'crypto-js';
const password = 'Valantis';
const timestamp = new Date().toISOString().slice(0, 10).split('-').join('');
const data = `${password}_${timestamp}`;
const authorizationString = CryptoJS.MD5(data).toString();;
export async function getStore() {
await fetch("http://api.valantis.store:40000/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Auth': authorizationString
},
body: JSON.stringify(
{
action: 'get_ids'
}
),
}).then( res => {
res.json().then(results =>
{let result = results
if (result !== undefined) {
console.log(result)
return result
}
})
}
);
}
Эту функцию я вызываю в state productStore в другом файле
import CryptoJS from 'crypto-js';
import { getStore } from './http/productStore';
const productsStore = {
productsList: getStore().then(res => console.log(res))
}
function reducer(state = productsStore, action) {
switch(action.type) {
case "SET_LIST": return {...state, productsList: action.products };
default: return state;
}
}
const store = createStore(reducer);
export default store;
, и в файле App.js вывожу в консоль этот state
import { useSelector } from'react-redux';
import ProductCard from './components/ProductCard';
import Container from 'react-bootstrap/Container';
import AsideMenu from './components/AsideMenu';
function App() {
const products = useSelector(state => state.productsList)
console.log(products)
return (
<Container style={{padding: "50px 30px 0 50px", display: "flex", justifyContent: 'space-between'}} className='d-flex '>
<Container style={{display: "flex", flexWrap: 'wrap'}}>
</Container>
<Container style={{border: "1px solid black", padding: '30px', backgroundColor: '#87cefa', minHeight: '300px'}}>
<AsideMenu></AsideMenu>
</Container>
</Container>
);
}
export default App;
, вот в итоге что получается
Ответы (2 шт):
Во первых, код getStore().then(res => console.log(res)) всегда вернет undefined, т.к. из последнего .then() ничего не возвращается.
Пример
// Это наш промис
async function test() {
return {
a: 'answer'
}
}
// Тут будем ждать выполнения
async function run() {
// Дожидаемся промисов и записываем рещзультат
const x = await test().then(x => console.log(1, x));
const y = await test().then(x => {
console.log(2, x);
return x
});
console.log('=========')
// Выводим значения переменных
console.log('x', x)
console.log('y', y)
}
// Запускаем
run();
Теперь модифицируем код, что бы он корректно работал и реагировал на изменение состояния.
Для начала зададим начальное состояние для хранилища
const productsStore = {
productsList: []
}
function reducer(state = { ...productsStore }, action) {
switch(action.type) {
case "SET_LIST": return {...state, productsList: action.products };
default: return state;
}
}
В компонент App добавляете вызов вашей функции при установке компонента
function App() {
const products = useSelector(state => state.productsList)
const dispatch = useDispatch();
useEffect(() => {
getStore().then(res => dispatch({type: 'SET_LIST', products: res}))
}, []);
// Тут ваш код рендера
}
Как компонент будет установлен в DOM, произойдет вызов вашей функции запроса данных. Когда данные придут, они сохранятся в stor redux и компонент обновится.
Ну и так как вы ожидаете в ответе массив, то что бы не было неожиданного поведения, в функции getStore я бы в then изменил код вот так, что бы всегда гарантированно приходил массив
.then(result => {
return result ? result : []; // Если пусто, пернуть пустой массив
})
.catch(err => []) // Если ошибка, вернуть пустой массив
Спасибо большое за помощь!
Вот конечный вариант вызова
import CryptoJS from 'crypto-js';
const password = 'Valantis';
const timestamp = new Date().toISOString().slice(0, 10).split('-').join('');
const data = `${password}_${timestamp}`;
const authorizationString = CryptoJS.MD5(data).toString();;
export async function getStore() {
const res = await fetch("http://api.valantis.store:40000/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Auth': authorizationString
},
body: JSON.stringify(
{
action: 'get_ids'
}
),
}).then(response => response ? response : []).catch((err) => [])
return res.json()
}
