Below is the code for my biggest nightmare yet. I keep on getting the error that the apiData.map is not a function. Any body that can help please.
I also need to know why ApiGetData do not use react please.
I do get the api data but seems that I'm importing it incorrectly to ClassFilmData and I get the .map error. All help will be appreciated.
Tried to export films, ApiGetData in various way. Help received from other platforms was implemented but did not solve the problem. Searches - other swapi projects, import data react, sandbox, repo and other platforms
// import React from 'react';
import { ApiToGet } from "./ApiToGet";
const ApiGetData = async function() {
try {
const films = await Promise.all(
ApiToGet.map(url => fetch(url).then(resp => resp.json()))
);
console.log("film title - ", films.results);
return films;
} catch (err) {
console.log("oooooooops", err);
}
};
ApiGetData();
export default ApiGetData;
import React from "react";
import FilmsInfo from "./FilmsInfo";
const FilmsLoop = ({ apiData }) => {
return (
<div className="tc f1 unknown">
{apiData.map((answers, i) => {
return (
<FilmsInfo
key={i}
// title={ apiData.films.results[i].title }
/>
);
})}
</div>
);
};
export default FilmsLoop;
import React, { Component } from "react";
import FilmsLoop from "./FilmsLoop";
import ApiGetData from "./ApiGetData";
class ClassFilmData extends Component {
render() {
return (
<div>
<p className="tc f1">Wim - classfilmdata</p>
<FilmsLoop apiData={ApiGetData} />
</div>
);
}
}
export default ClassFilmData;
import React from "react";
const FilmsInfo = () => {
return (
<div className="tc bg-light-blue dib br3 pa3 ma3 grow bw2 shadow-5">
<p>Planet</p>
<p>FilmsInfo.js</p>
</div>
);
};
export default FilmsInfo;
That is because apiData is really ApiGetData which is a promise.
If you're trying to use the array returned by resolving this promise, you'll have to do something like this:
class ClassFilmData extends Component {
componentDidMount() {
const apiData = await ApiGetData();
this.setState({ apiData });
}
render() {
return(
<div>
<p className="tc f1">Wim - classfilmdata</p>
{this.state.apiData && <FilmsLoop apiData={ this.state.apiData }/> }
</div>
);
}
}
Related
I'm currently making a simple web frontend with react using react-autosuggest to search a specified user from a list. I want to try and use the Autosuggest to give suggestion when the user's type in the query in the search field; the suggestion will be based on username of github profiles taken from github user API.
What I want to do is to separate the AutoSuggest.jsx and then import it into Main.jsx then render the Main.jsx in App.js, however it keeps giving me 'TypeError: _ref2 is undefined' and always refer to my onChange function of AutoSuggest.jsx as the problem.
Below is my App.js code:
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import Header from './views/header/Header';
import Main from './views/main/Main';
import Footer from './views/footer/Footer';
const App = () => {
return (
<>
<Header/>
<Main/> <- the autosuggest is imported in here
<Footer/>
</>
);
}
export default App;
Below is my Main.jsx code:
import React, { useState } from 'react';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import axios from 'axios';
import { useEffect } from 'react';
import AutoSuggest from '../../components/AutoSuggest';
const Main = () => {
const [userList, setUserList] = useState([]);
useEffect(() => {
axios.get('https://api.github.com/users?per_page=100')
.then((res) => setUserList(res.data))
.catch((err) => console.log(err));
}, [])
return (
<Container>
<br/>
<Row>
<AutoSuggest userList={userList} placeHolderText={'wow'} />
</Row>
</Container>
);
}
export default Main;
Below is my AutoSuggest.jsx code:
import React, { useState } from "react";
import Autosuggest from 'react-autosuggest';
function escapeRegexCharacters(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function getSuggestions(value, userList) {
const escapedValue = escapeRegexCharacters(value.trim());
if (escapedValue === '') {
return [];
}
const regex = new RegExp('^' + escapedValue, 'i');
return userList.filter(user => regex.test(user.login));
}
function getSuggestionValue(suggestion) {
return suggestion.name;
}
function renderSuggestion(suggestion) {
return (
<span>{suggestion.name}</span>
);
}
const AutoSuggest = ({userList, placeHolderText}) => {
const [value, setValue] = useState('');
const [suggestions, setSuggestions] = useState([]);
const onChange = (event, { newValue, method }) => { <- error from console always refer here, I'm not quite sure how to handle it..
setValue(newValue);
};
const onSuggestionsFetchRequested = ({ value }) => {
setValue(getSuggestions(value, userList))
};
const onSuggestionsClearRequested = () => {
setSuggestions([]);
};
const inputProps = {
placeholder: placeHolderText,
value,
onChange: () => onChange()
};
return (
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={() => onSuggestionsFetchRequested()}
onSuggestionsClearRequested={() => onSuggestionsClearRequested()}
getSuggestionValue={() => getSuggestionValue()}
renderSuggestion={() => renderSuggestion()}
inputProps={inputProps} />
);
}
export default AutoSuggest;
The error on browser (Firefox) console:
I have no idea what does the error mean or how it happened and therefore unable to do any workaround.. I also want to ask if what I do here is already considered a good practice or not and maybe some inputs on what I can improve as well to make my code cleaner and web faster. Any input is highly appreciated, thank you in advance!
you have to write it like this... do not use the arrow function in inputProps
onChange: onChange
I am using Easy Peasy State management for React. I would like to create multiple Axios call from one store location and import it in each page there where I need to show the correct data. I am trying to fetch a JSON placeholder data for example and use that inside a component to push it to the state using Hooks.
But I get the following error:
model.js:14 Uncaught (in promise) TypeError: actions.setTodos is not a function
at model.js:14
Can someone help me out? What am I doing wrong?
My code for the store (model.js):
import { thunk } from 'easy-peasy';
export default {
todos: [],
fetchTodos: thunk(async actions => {
const res = await fetch(
'https://jsonplaceholder.typicode.com/todos?_limit=10'
);
const todos = res.json();
actions.setTodos(todos);
}),
};
My Page component Contact:
import React, { useState, useEffect } from 'react';
import { useStoreActions } from 'easy-peasy';
import ReactHtmlParser from 'react-html-parser';
import { API_URL } from 'constants/import';
// import axios from 'axios';
const Contact = () => {
const [contactPage, setContactPage] = useState([]);
const { page_title, page_content, page_featured_image } = contactPage;
const fetchTodos = useStoreActions(actions => actions.fetchTodos);
useEffect(() => {
fetchTodos();
}, []);
return (
<section className="contact">
<div className="page">
<div className="row">
<div className="col-xs-12">
<h3 className="section__title">{page_title}</h3>
{ReactHtmlParser(page_content)}
{page_featured_image && (
<img src={API_URL + page_featured_image.path} />
)}
</div>
</div>
</div>
</section>
);
};
export default Contact;
You need to use action.
import { action, thunk } from "easy-peasy";
export default {
fetchTodos: thunk(async (actions, payload) => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/todos?_limit=10"
);
const todos = res.json();
actions.setTodos(todos);
}),
todos: [],
setTodos: action((state, payload) => {
console.log("---->>> payload!")
state.todos = payload
}),
};
I usually use it like this, it works perfectly for me.
Doing a Hacker News Clone tutorial in React and Next.js, but I'm stumbling into a problem. I have read other questions that are dealing with the same error, but the solutions offered don't work for me. Here is the code:
import React from 'react';
const StoryList = ({ stories }) => (
<div>
{stories.map(story => (
<h3 key={story.id}>{story.title}</h3>
))}
</div>
);
export default StoryList;
The error is specifically at line 4 of that, on the first div tag.
Here is my index page:
import React from 'react';
import fetch from 'isomorphic-fetch';
import Error from 'next/error';
import StoryList from '../components/StoryList';
class Index extends React.Component {
static async getInitialProps() {
let stories;
try {
const response = await fetch(
'https://node-hnapi.herokuapp.com/news?page=1'
);
stories = await response.json();
} catch (err) {
console.log(err);
stories = []
}
return { stories };
}
render() {
const { stories } = this.props;
if (stories.length === 0) {
return <Error statusCode={503} />;
}
return (
<div>
<h1>Hacker News Clone</h1>
<StoryList storeis={stories} />
</div>
)
}
}
export default Index;
you have used storeis prop and using as stories
see this,
<div>
<h1>Hacker News Clone</h1>
<StoryList storeis={stories} /> // here prop is storeis
</div>
and used as this,
const StoryList = ({ stories }) => ( // and here using as stories
<div>
{stories.map(story => (
<h3 key={story.id}>{story.title}</h3>
))}
</div>
);
make both same.
I feel that was spell mistake.
I'm building a search engine with React.js, where I can look for GIPHY gifs, using their API. When I type a word in the search bar, I get this error: Uncaught (in promise) TypeError: props.gifs.map is not a function
at GifList (SelectedList.js:19)
The console log returns an array, tough :
import React from 'react';
import GifItem from './SelectedListItem';
const GifList = (props) => {
console.log(props.gifs); // Logs Array in the console
const gifItems = props.gifs.map((image) => { // <=======
return <GifItem key={image.id} gif={image} />
});
return (
<div className="gif-list">{gifItems}</div>
);
};
export default GifList;
How is fetching the gifs:
import React from 'react'; //react library
import ReactDOM from 'react-dom'; //react DOM - to manipulate elements
import './index.css';
import SearchBar from './components/Search';
import GifList from './components/SelectedList';
class Root extends React.Component { //Component that will serve as the parent for the rest of the application.
constructor() {
super();
this.state = {
gifs: []
}
this.handleTermChange = this.handleTermChange.bind(this)
}
handleTermChange(term) {
console.log(term);
let url = 'http://api.giphy.com/v1/gifs/search?q=${term.replace(/\s/g, '+')}&api_key=dc6zaTOxFJmzC';
fetch(url).
then(response => response.json()).then((gifs) => {
console.log(gifs);
console.log(gifs.length);
this.setState({
gifs: gifs
});
});
};
render() {
return (
<div>
<SearchBar onTermChange={this.handleTermChange} />
<GifList gifs={this.state.gifs} />
</div>
);
}
}
ReactDOM.render( <Root />, document.getElementById('root'));
Any help is appreciated! Thanks! :)
As per your comment, props.gifs is an object and props.gifs.data is an array. So you need to write
const gifItems = props.gifs && props.gifs.data && props.gifs.data.map((image) => {
return <GifItem key={image.id} gif={image} />
});
Maybe I'm missing something here, but I'm not getting data flowing from my db into my component.
I'm using react and meteor (w/ mantra), using simpleSchema/collection2 on the server. As far as I can tell I've got my publish/subscribe setup properly.
I've built things out with the mantra cli. (Which by the way is awesome)
Heres's my setup:
Component: (client/modules/components/sidebar_hubs.js)
import React from 'react';
const renderIfData = ( hubs ) => {
if ( hubs && hubs.length > 0 ) {
return hubs.map( ( hub ) => {
return <li key={ hub._id }>{ hub.name }</li>;
});
} else {
return <p>No hubs yet!</p>;
}
};
const SidebarHubs = ({hubs}) => (
<div>
<h1> Hubs </h1>
{hubs.length}
<ul> { renderIfData( hubs ) } </ul>
</div>
);
export default SidebarHubs;
Container (client/modules/containers/sidebar_hubs.js)
import {useDeps, composeAll, composeWithTracker, compose} from 'mantra-core';
import SidebarHubs from '../components/sidebar_hubs.js';
export const composer = ({context}, onData) => {
const {Meteor, Collections} = context();
const subscription = Meteor.subscribe( 'hubs' );
if ( subscription.ready() ) {
const hubs = Collections.Hubs.find().fetch();
onData( null, { hubs } );
}
};
export const depsMapper = (context, actions) => ({
context: () => context
});
export default composeAll(
composeWithTracker(composer),
useDeps(depsMapper)
)(SidebarHubs);
Publication:(server/publications/hubs.js)
import {Hubs} from '/lib/collections';
import {Meteor} from 'meteor/meteor';
import {check} from 'meteor/check';
export default function () {
Meteor.publish('hubs', function () {
return Hubs.find();
});
}
What am I missing obvious here?
This confusing to debug as nothing was breaking... And the component was being rendered, just without data.
Tossed a couple of console.logs around and it seemed like my container wasn't even being ran. As I figured it was something obvious ugh.... In my main_layout.js file.
From
import SidebarHubs from '../components/sidebar_hubs.js';
to:
import SidebarHubs from '../containers/sidebar_hubs.js';
Works like a charm now. Good debugging skills go a long way...