TypeError: allOrg.map is not a function [closed] - react-functional-component

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am trying to loop through all the objects in a array state in react, hence I used map function. Here is the block of code where I used the map function:
return(
<div>
<Navbar/><br/>
{
allOrg.map((data: orgType, index: number) => {
/*<Org key={index} userId = {UserId} orgName = {data.orgName} /> */
<h1>{index} {UserId} {data.orgName}</h1>
})
}
<div className = "OrgRow">
<button className = "OrgTeams" onClick={createOrg}>Add Org</button>
{createOrgForm}
</div>
</div>
)
But it is showing me "TypeError: allOrg.map is not a function" error. picture of the error I looked for similar errors on stackoverflow, but only suggestions were that map can only be used with arrays. And here my state is an array only, still this problem is persisting. Here is my declaration of the state named "allOrg":
import React,{useState, useEffect} from "react";
import { useForm } from "react-hook-form";
import Navbar from "./navBar";
import Org from "./org";
import "../../style/auth.css";
import "../../style/home.css";
interface orgType{
orgId: string;
orgName: string;
}
function Home(): JSX.Element{
//let UserId: string = "Ronak";
const initialOrg = {
orgId: "",
orgName: ""
}
const [UserId, setUserId] = useState<string>("userId");
const [createOrgForm, setForm] = useState(<div></div>);
const [allOrg, setAllOrg] = useState<orgType[]>([initialOrg]);
const [orgAdded, changeState] = useState(true);
const {register, handleSubmit} = useForm();
I am also pasting images containing my entire code for that component:
import React,{useState, useEffect} from "react";
import { useForm } from "react-hook-form";
import Navbar from "./navBar";
import Org from "./org";
import "../../style/auth.css";
import "../../style/home.css";
interface orgType{
orgId: string;
orgName: string;
}
function Home(): JSX.Element{
//let UserId: string = "Ronak";
const initialOrg = {
orgId: "",
orgName: ""
}
const [UserId, setUserId] = useState<string>("userId");
const [createOrgForm, setForm] = useState(<div></div>);
const [allOrg, setAllOrg] = useState<orgType[]>([initialOrg]);
const [orgAdded, changeState] = useState(true);
const {register, handleSubmit} = useForm();
const submitButton = {
margin: "auto",
marginTop: 30,
display: "block"
}
useEffect(() => {
fetch('/api/v1/auth/verifyJWT', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
})
.then(res => res.json())
.then(data => {
console.log(data.serviceResponse.userId);
setUserId(data.serviceResponse.userId);
console.log(UserId);
}
)
}, [] )
useEffect( () => {
console.log(UserId);
fetch('/api/v1/org/all/' + UserId)
.then(res => res.json())
.then(data => {
setAllOrg(data);
console.log("Hi");
console.log(data);
console.log(allOrg);
console.log("bye");
}
)}, [UserId]);
function onSubmit(data: any){
fetch('/api/v1/org/create', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => {
console.log(data);
if(data.message == "Created!"){
console.log("successful");
setForm(()=><div></div>);
changeState(!orgAdded);
}
else{
console.log("failed");
}
})
}
function createOrg(){
console.log(UserId);
setForm(()=>
<form className = "auth_form" onSubmit = {handleSubmit(onSubmit)}>
<br/><br/>
<input className = "auth_input" {...register("userId", {required: true})} name="userId" value={UserId}/>
<br/>
<input className = "auth_input" {...register("orgName", {required: true})} name="orgName" placeholder="Organization Name"/>
<br/>
<button className = "auth_button" style={submitButton} type="submit">Create</button>
</form>
)
}
return(
<div>
<Navbar/><br/>
{
allOrg.map((data: orgType, index: number) => {
/*<Org key={index} userId = {UserId} orgName = {data.orgName} /> */
<h1>{index} {UserId} {data.orgName}</h1>
})
}
<div className = "OrgRow">
<button className = "OrgTeams" onClick={createOrg}>Add Org</button>
{createOrgForm}
</div>
</div>
)
}
export default Home;
Line 103 is where I used allOrg.map() and the declaration of allOrg state is at the start of the function.
Any help would be welcome.
P.S. Incase anyone thinks that the allOrg state might be empty, it is not so. I checked using console.log..
Edit: I am adding the ss of console.log of allOrg, console.log(allOrg).

Even if you checked that allOrg is state is not empty it might be possible that component is rendered multiple times where first time allOrg is at initial state for second rendering it might be empty or null or undefined and at last when API call is completed it fills allOrg.
So you have to handle case for when allOrg is null or something.
let orgList;
if(Array.isArray(allOrg)){
orgList = allOrg.map(
...
);
}
render (
...
{orgList}
...
);

Related

How to limit the number of options in a select?

I am working on a project using React and tailwind.
I would like to filter the options I mean I want see to at most 3 options. I tried slice but it is not a solution because using slice for instance if I type a I want to see at most 3 words which contains the letter a if I type b I want to see at most 3 words which contains the letter b and that words for a and b can be different so slice cannot be a solution.
Here is my code :
import React, { Component } from "react";
import Select, { components} from "react-select";
import { useState } from "react";
let cheeses = ["Wagasi", "Kalari", "Halloumi", "Manouri"];
let options = [];
options = options.concat(cheeses.map((x) => "Cheese - " + x));
const Foo = () => {
const [value, setValue] = useState("");
function MakeOption(x) {
if (value) {
return { value: x, label: x };
} else {
return { value: "", label: "" };
}
}
const handleInputChange = (value, e) => {
if (e.action === "input-change") {
setValue(value);
}
};
const Input = props => <components.Input {...props} maxLength={5} />;
return (
<Select
isMulti
name="colors"
options={options.map((x) => MakeOption(x)).filter(opt => opt.value !== "")}
className="basic-multi-select"
classNamePrefix="select"
closeMenuOnSelect={false}
onInputChange={handleInputChange}
inputValue={value}
noOptionsMessage={() => null}
/>
);
};
export default Foo;
Could you help me please ?
I think this code works like you want.
The problem have been solved with a second variable for the select options.
import React, { Component } from "react";
import Select, { components} from "react-select";
import { useState } from "react";
let cheeses = ["Wagasi", "Kalari", "Halloumi", "Manouri"];
let options = [];
options = options.concat(cheeses.map((x) => "Cheese - " + x));
const Foo = () => {
const [value, setValue] = useState("");
const [optionsToShow, setOptionsToShow] = useState([]);
function MakeOption(x) {
return { value: x, label: x };
}
const handleInputChange = (value, e) => {
if (e.action === "input-change") {
setValue(value);
const nextOptions = value ? options.map((x) => MakeOption(x)).filter((opt) => opt.label.toLowerCase().includes(value.toLowerCase())) : [];
setOptionsToShow(nextOptions.length > 3 ? nextOptions.splice(1,3) : nextOptions);
}
};
const Input = props => <components.Input {...props} maxLength={5} />;
return (
<Select
isMulti
name="colors"
options={optionsToShow}
className="basic-multi-select"
classNamePrefix="select"
closeMenuOnSelect={false}
onInputChange={handleInputChange}
inputValue={value}
noOptionsMessage={() => null}
/>
);
}
export default Foo;
I hope I've helped you

React : i have following code, i am using setInterval to change text value time to time ,when i switch pages and come back text is changing reallyfast

I assume when component is rendered multiple times something happens to setinterval,but how can i fix this.
bottom code is for Store that i am using and i don't understand.someone said that i must have useffect outside component but then it gives me error.
Anyways im new to react so i need help ,everyones appriciated.Thanks.
import SmallLogo from '../img/logo.svg';
import StarskyText from '../img/starskyproject.svg';
import './Statement.css'
import { BrowserRouter as Router,Routes,Route,Link } from "react-router-dom";
import { getElementError } from '#testing-library/react';
import react, { useRef , useState, useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
import { store } from "./appReducer";
function TempText(props) {
return <span className="yellow changetext"> {props.body} </span>;
}
function doUpdate(callback) {
setInterval(callback, 1300);
}
export default function Statement(){
const dispatch = useDispatch();
const textOptions = ["NFT", "CRYPTO", "METAVERSE", "WEB3"];
const tempText = useSelector((state) => state.tempText);
function change() {
let state = store.getState();
const index = state.index;
console.log(index);
console.log(textOptions[index]);
dispatch({
type: "updatetext",
payload: textOptions[index]
});
let newIndex = index + 1 >= textOptions.length ? 0 : index + 1;
dispatch({
type: "updateindex",
payload: newIndex
});
}
useEffect(() => {
doUpdate(change);
}, []);
var [dropdownOpen , Setdrop] = useState(false);
return(
<div>
<Link to="/">
<img className='star-fixed' alt='starlogo' src={SmallLogo}></img>
</Link>
<img className='starsky-fixed' alt='starsky-project' src={StarskyText}></img>
<div className='text-content'>
<span className='statement-text'>WEB3 IS NOT ONLY THE FUTURE.
IT’S THE ONLY FUTURE!</span>
<span className='starsk-link'>starsk.pro</span>
</div>
<div className='text-content-bottom'>
<span className='statement-text-bottom'>CREATE YOUR NEXT
<TempText body={tempText} />
<span className='flex'> PROJECT WITH
<Dropdown className="hover-drop-out" onMouseOver={() => Setdrop(dropdownOpen=true) } onMouseLeave={() => Setdrop(dropdownOpen=false)} isOpen={dropdownOpen} toggle={() => Setdrop(dropdownOpen = !dropdownOpen) }>
<DropdownToggle className='hover-drop'> STRSK.PRO </DropdownToggle>
<DropdownMenu> </DropdownMenu>
</Dropdown> </span>
</span>
</div>
</div>
)
}
import { createStore } from "redux";
const initialState = {
tempText: "NFT",
index: 1
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "updatetext":
return {
...state,
tempText: action.payload
};
case "updateindex":
return {
...state,
index: action.payload
};
default:
return state;
}
};
export const store = createStore(reducer);
You can clear your timer by calling clearTimeout function with a reference to your timer when your component unmounting.
useEffect(() => {
const timer = setInterval(change, 1300);
// in order to clear your timeout
return () => clearTimeout(timer);
}, [])

Trouble getting into json data object

I have some code that allows the user to click a image to then update the page and display the clicked on champions name. the json data looks like this -http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/Alistar.json
I console.log response.data and see a object of objects and am wondering how to get passed the section that has the response.data.(whatever champion the user picked). I have tried adding a variable like response.data.champion but I assume no variables can be passed like that seeing how it doesnt work.
Not sure if its even worth posting the code but just in case! My code is below, the fetch im trying to go through is in NewChamp function.
To make my request simpler, All i want to know for example is how i would get response.data.(whatever the user clicked).key from any possible champion clicked like http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/Alistar.json or http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/Anivia.json
or whatever other champion the user clicks.
import React, { Component } from 'react';
import './Champions.css';
class AllChamps extends Component {
render() {
let champion = this.props.champion;
return(
<div className='champions'>
<h1> all champions</h1>
{Object.keys(this.props.champions).map((s) => (
<div className='champs' onClick={() => this.props.NewChamp({s, champion})}>
<img
alt='Champion Images'
src={`http://ddragon.leagueoflegends.com/cdn/10.16.1/img/champion/${s}.png`}
onClick={this.props.onClick}
></img>
{s}
</div>
))}
</div>
)}}
class SpecificChamp extends Component {
render() {
let champion = this.props.champion
let Spec = champion[champion.length - 1];
return (
<div className='champions'>
<h1> 1 champions</h1>
<div className='champs'>
<button onClick={this.props.onClick}></button>
{Spec}
</div>
</div>
)}
}
class Champions extends Component {
constructor(props) {
super(props);
this.handleAllChamps = this.handleAllChamps.bind(this);
this.handleSpecificChamp = this.handleSpecificChamp.bind(this);
this.NewChamp = this.NewChamp.bind(this);
this.state = {
champions: [],
champion: [],
clickedChamp: false,
thisChamp: 'ahri'
}}
NewChamp = (props) =>
{
let s = props.s;
props.champion.push(s);
fetch(`http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/${s}.json`)
.then(response => { return response.json() })
.then((response) => {
Object.keys(response.data).map((a) => (s = a
))})
fetch(`http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/${s}.json`)
.then(response => { return response.json() })
.then((response) => {
console.log(s)
console.log(response.data)
console.log(props.champion)
})
console.log(`http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion/${s}.json`);
}
handleAllChamps = (props) => {
this.setState({ clickedChamp: true,
})};
handleSpecificChamp = () => {
this.setState({ clickedChamp: false,
})};
componentDidMount(props) {
const apiUrl = `http://ddragon.leagueoflegends.com/cdn/10.16.1/data/en_US/champion.json`;
fetch(apiUrl)
.then(response => { return response.json() })
.then((response) => {
this.setState({
champions: response.data
}, () => (this.state.champions))
return
})
}
render() {
const clickedChamp = this.state.clickedChamp;
let display;
if (clickedChamp ) {
display = <SpecificChamp champion={this.state.champion} onClick={this.handleSpecificChamp} s={this.state.thisChamp}/>;
} else {
display = <AllChamps champions={this.state.champions} onClick={this.handleAllChamps} NewChamp={this.NewChamp} thisChamp={this.state.thisChamp} champion={this.state.champion} />;
}
return (
<div>
<div className='champions'></div>
{display}
</div>
);
}
}
export default Champions;
Your response is in the form of Object of Objects. You've to use JSON.stringify(response.data) in order to view the entire data as a string in the debug console.
You will have to destructure the Object of objects.
Object.keys(response.data).map((key)=> console.log(response.data[key]))
In this case if it is just one key
response.data[s]

Reactjs fetch method returns empty array

I am trying to fetch some data, which is in the form:
[
{
"id": 1,
"some_data": "..."
},
...
]
What I am trying to get is a list displaying the items from the fetch. If I put the same data in a file within the project, it works.
However when I tried to map it, I got an error saying "this.data.map is not a function". So I changed it a bit by using Array.from(). It currently looks like this:
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
items = [];
};
this.getData = this.getData.bind(this);
}
getData = () => {
fetch("URL",{
method: "get",
header: { "Content-Type": "application/json" }
})
.then(response => {
var array = Array.from(response.json())
this.setState({items: array});
})
}
render() {
const list = this.state.items.map((r, i) => {
return (
<Item
id = { r[i].id }
some_data = { r[i].some_data }
...
/>
)
})
return(
<div>
<Item
p = {list}
>
</div>
)
}
}
First of all no state is neede to store the response. Its happening due to the state value is not reflecting in your render.
Call a function inside success response & map the response inside the function & set State there.
OR
Put the below code outside render function assigning to variable like below
const list = this.state.items.map((r, i) => {
return (
)
})
return(
)
}
render () {
{list}
}
Try something like this.....
It's better to load the data once component is mounted. Also, there's no URL, I'm assuming that you've hidden this.
Once you 'see' what's in response, you can code against that accordingly.
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
items = [];
};
// this.getData = this.getData.bind(this);
}
componentDidMount(){
// Attempt to load data once component mounted.
this.getData();
}
getData = () => {
// Don't you need the URL below, or have you deliberately hidden it?
fetch("URL",{
method: "get",
header: { "Content-Type": "application/json" }
})
.then(response => {
console.log(response); // See exactly what is in response....
var array = Array.from(response.json())
console.log(array); // Check array is really what you want
// You could try a JSON.Parse....
var jsonArray = JSON.Parse(response);
console.log(jsonArray);
this.setState({items: array});
})
}
render() {
const list = this.state.items.map((r, i) => {
return (
<Item
id = { r[i].id }
some_data = { r[i].some_data }
...
/>
)
})
return(
<div>
<Item
p = {list}
>
</div>
)
}
}

Redux loses state when navigating to another page using react-router 'history.push'

(as you can see my reputation is not very high :) and I understand that if you don't like my question it is going to be my last one, therefore I am going to write it as good as I can :)
The problem I am facing is a similar to:
Redux loses state when navigating to another page
However, the answer to the above question was to use 'history.push', which is what I am doing, and I am still having a problem.
I am using:
"react": "^16.0.0"
"react-redux": "^5.0.6"
"react-router": "^4.2.0"
"react-router-dom": "^4.2.2"
"redux": "^3.7.2"
"redux-promise":"^0.5.3"
"axios": "^0.17.1"
I am doing the following:
In a react component, "SearchText", getting a text string and calling an action creator
In the action creator, using the text string to send an HTTP request to goodreads.com
In my reducer, using the action payload to set the redux state
Using another component, "BookResults" (in another route), to display this state
The component "SearchText" has a link to the "BookResults" page.
So, once "SearchText" fires the action creator, if (when I see on the console that a result is received and the state is set with a list of books) I click on the link that routes to "BookResults", I see the list of books.
If, however, "SearchText" uses (when firing the action creator) a callback that performs history.push of the new page, and this callback is called by 'axios(xxx).then', the state is not set properly, although I see in the console that the HTTP request was successful.
I am sure you can see what I am doing wrong (and I hope it is not very stupid)... Please tell me.
Here is the code:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';
import SearchText from './components/search_text';
import BookResults from './components/book_results';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<div>
<BrowserRouter>
<Switch>
<Route path="/book_results" component={BookResults} />
<Route path="/" component={SearchText} />
</Switch>
</BrowserRouter>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('#root'));
SearchText component
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router-dom';
import { searchForBooks } from '../actions';
class SearchText extends Component {
constructor(props) {
super(props);
this.state = {
searchText: ''
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
}
handleSearchTextChange(e) {
this.setState({ searchText: e.target.value });
}
handleFormSubmit(e) {
e.preventDefault();
const formPayload = {
searchText: this.state.searchText
};
console.log("In SearchBooks/handleFormSubmit. Submitting. state: ", this.state);
this.props.searchForBooks(formPayload, () => {
this.props.history.push(`/book_results`);
});
}
render() {
return (
<form className="container" onSubmit={this.handleFormSubmit}>
<h3>Search Form</h3>
<div className="form-group">
<label className="form-label">{'Search Text:'}</label>
<input
className='form-input'
type='text'
name='searchText'
value={this.state.searchText}
onChange={this.handleSearchTextChange}
onBlur={this.handleSearchTextBlur}
placeholder='' />
</div>
<br />
<input
type="submit"
className="btn btn-primary float-right"
value="Submit"/>
<br /><br />
<Link to={`/book_results`}>⇐ Book Results</Link>
</form>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ searchForBooks: searchForBooks }, dispatch);
}
export default connect(null, mapDispatchToProps)(SearchText);
BookResults component
import React from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';
import Book from './book';
class BookResults extends React.Component {
render() {
let books;
const booksArray = _.values(this.props.bookResults);
console.log("***In BookResults. booksArray: ", booksArray);
if (booksArray.length === 0) {
books = "No books to display";
} else {
books = booksArray.map( (book) => {
return (
<Book book={book} key={book.id} />
);
});
}
return (
<div>
<h2>Search Results</h2>
<br />
<ul>
{books}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
return {
bookResults: state.bookResults,
cats: state.cats
};
}
export default connect(mapStateToProps)(BookResults);
Book component
import React from 'react';
const Book = (props) => (
<li>
{props.book.title}
</li>
);
export default Book;
actions/index.js
As you can see below, the following line is commented out:
// .then(() => callback());
If I include it, I have the problem.
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl);
// .then(() => callback());
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
reducers/index.js
import { combineReducers } from 'redux';
import bookResultsReducer from './reducer_book_results';
const rootReducer = combineReducers({
bookResults: bookResultsReducer
});
export default rootReducer;
The reducer
import { parseString } from 'xml2js';
import _ from 'lodash';
import { SEARCH_FOR_BOOKS } from '../actions/index';
const bookResults = {};
export default function bookResultsReducer(state = bookResults, action) {
switch (action.type) {
case SEARCH_FOR_BOOKS:
console.log("In bookResultsReducer. payload: ", action.payload);
if (action.error) { // error from goodreads search books
console.error("*** APP ERROR *** In bookResultsReducer. action.error: ", action.error);
} else if (!action.payload || !action.payload.data) {
console.error("*** APP ERROR *** In bookResultsReducer." +
" action.payload or action.payload.data is undefined", action.payload);
} else {
parseString(action.payload.data, function(err, result) {
if (err) {
console.error("*** APP ERROR *** In bookResultsReducer. Error from parseString: ", err);
} else {
state = Object.assign({}, getBooks(result));
}
});
}
console.log("In bookResultsReducer. new state: ", state);
return state;
break;
default:
return state;
}
}
function getBooks(data) {
const bookResults = data.GoodreadsResponse.search[0].results[0].work;
if (!bookResults || bookResults.length === 0) {
return {};
} else {
const results = bookResults.map( (book, index) => {
const bookInfo = book.best_book[0];
return (
{ id: index + 1,
title: bookInfo.title[0] }
);
});
return _.mapKeys(results, 'id');
}
}
Someone sent me the solution by mail.
The error was in the actions/index.js file.
Instead of:
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl)
.then(() => callback());
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
I should have written:
import axios from 'axios';
export const SEARCH_FOR_BOOKS = 'search_for_books';
const GOODREADS = "https://www.goodreads.com/search/index.xml";
const KEY = "xxx";
export function searchForBooks(values, callback) {
let result;
console.log("In actions/searchForBooks. values: ", values);
if (!values.searchText || values.searchText === "") {
console.error("*** ERROR *** In actions/searchForBooks." +
"values.searchText: ", values.searchText);
} else {
const searchUrl = `${GOODREADS}?key=${KEY}&q=${values.searchText}`;
console.log("In actions/searchForBooks. url: " + searchUrl);
result = axios.get(searchUrl)
.then((res) => {
callback();
return res;
});
}
return {
type: SEARCH_FOR_BOOKS,
payload: result
};
}
Explanation:
The issue is that the returned value from axios.get is passed to the .then clause, and whatever is returned from the .then clause is set to be the value of result.
My error was that I didn't return anything from the .then clause, and therefore the value of result was undefined, and not the returned promise.