Reactjs Event/Action Button not switching as expected - reactjs

Reactjs Event/Action Button not switching as expected.
Am trying to add follow and unfollow action button. when I post via axios via Follow button,
it post to data to server backend and return success message. Then the Follow button switched to Unfollow button.
Now my problem is that Unfollow button is not switching back to Follow Button when User try to unfollow someone.
Please what am I doing wrong here.
here is the json success message
[{"status":"success", "follow":"1", "unfollow":"0"}]
here is the my code
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
result_data: '',
data: [],
loading: false
};
}
componentDidMount() {
this.setState({
data: [{"uid":"1","name":"Nancy"},{"uid":"2","name":"Moore"}],
});
}
// update user following
handleFollowUser(user_id) {
const uid_data = { user_id: user_id };
axios
.get("http://localhost/data.json", { uid_data })
.then(response => {
this.setState(state => ({
//data: newData,
result_data: response.data[0].status
}));
alert(result_data);
})
.catch(error => {
console.log(error);
});
}
// update user unfollowing
handleUnFollowUser(user_id) {
const uid_data = { user_id: user_id };
axios
.get("http://localhost/data.json", { uid_data })
.then(response => {
this.setState(state => ({
//data: newData,
result_data: response.data[0].status
}));
alert(result_data);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<span>
<label>
<ul>
<h1>Users</h1> <br />
{this.state.result_data }
{this.state.data.map((users) => {
return (
<div key={users.uid}>
<div>
<b> Name: </b>{users.name}
<br />
{this.state.result_data === ''
? <span onClick={() =>
this.handleFollowUser(users.uid)}>Follow</span>
: <span onClick={() =>
this.handleUnFollowUser(users.uid)}>unfollow</span>
}
</div>
</div>
)
}
)}
</ul>
</label>
</span>
);
}
}

This is what solved my Reactjs problem.I first initialize
isToggleOn: !state.isToggleOn in the click event and in the constructor I implemented
this.state = {isToggleOn: true};
My click button becomes
<button onClick={this.handleFollowUser}>
{this.state.isToggleOn ? 'Follow' : 'Unfollow'}
</button>

Related

How I do use fetch API and store response in the state?

I have to get a file from the server, After the component is rendered, that contains information from cities, and I must assign it to "citiesData" in the state. But the data is not received because it is not seen in the output.
what is the issue with my fetch?
server file:
IranMap(the file seems to have a problem in fetch):
import React from 'react';
import './IranMap.css';
import CityModal from './CityModal';
class IranMap extends React.Component {
state = {
error: null,
citiesData: null,
selectedCity: null,
isModalOpen: false,
};
componentDidMount() {
fetch('http://localhost:9000/cities')
.then(response => response.json())
.then((result) => {
this.setState({
citiesData: result
});
},
(error) => {
this.setState({
error
});
}
)
}
cityClicked = (id) => (event) => {
event.preventDefault();
fetch(`http://localhost:9000/cities/${id}`,{method: 'GET'})
.then(res => res.json())
.then(result => {
this.setState({
selectedCity: result,
isModalOpen: true
});
})
}
closeModal = () => {
this.setState({
isModalOpen: false,
});
};
render() {
if(this.state.error){
return <div>Error: {this.state.error.message}</div>;
}
else {
return (
<div>
<div className="map-container">
{(this.state.citiesData || []).map((record) => (
<div
key={record.id}
className="city-name"
style={{
top: `${record.top}%`,
left: `${record.left}%`,
}}
onClick={this.cityClicked(record.id)}
>
{record.name}
</div>
))}
</div>
<CityModal
city={this.state.selectedCity}
isOpen={this.state.isModalOpen}
onClose={this.closeModal}
/>
</div>
);
}
}
}
export default IranMap;
This is my output. it should be show cities name. but this is empty:
I think what you are trying to do is render the entire object,u cant do that, try the render each element, The second part of my answer is that you should use an asynchronous task.
I hope my answer guided you

ASP.NET Core API and React JS

I have created ASP.NET Core API and React CURD practice example. I am following this example
but I've used react semantic ui for view. I am new to react and ASP.NET any suggestion so that I can improve my code.
I am able to fetch,POST,PUT and DELETE customer record but there are some small issues or point that I don't know how to implement. Those are as following
1 - I have used Modal so I can open form as popup (AddCustomer is form to add and edit record) in that I have two functions to OPEN and CLOSE the Modal but I don't how to call them from Customer.js and also on successful POST,PUT, DELETE request.
2 - When I open FORM to ADD or EDIT record I am not able to store that in state. When I try to type in input field it does not store in name and address.
3 - Also you can see in Customer.js I am hiding the form and delete modal but I want to close them on POST, PUT and DELETE task completion.
This is Customer.js
import React from 'react';
import AddCustomer from './AddCustomer';
import CustomerView from './CustomerView';
import DeleteRecord from './DeleteRecord';
export default class Customer extends React.Component {
constructor(props) {
super(props);
this.state = {
isAddCustomer:false,
isEditCustomer:false,
isDeleteCustomer:false,
closeForm:false,
singleCustomer:{},
deleteId:{}
}
}
onCreate = () => {
console.log("is add customer true ")
this.setState({isAddCustomer:true})
}
onFormControl = () =>{
this.setState({
isAddCustomer:false,
isEditCustomer:false
})
}
onDeleteClick = customerId => {
const headerTitle = "Customer";
console.log("onDeleteClick")
this.setState({
isDeleteCustomer:true,
deleteId:{
ID:customerId,
title:headerTitle,
open:true
}
});
}
//New Customer record
onAddFormSubmit = data => {
console.log("In add form submit")
console.log(data)
let customerApi = 'https://localhost:44387/api/Customers';
let method = '';
if(this.state.isEditCustomer){
console.log("In Edit api")
console.log(this.state.editCustomerId)
customerApi = 'https://localhost:44387/api/Customers/' + this.state.editCustomerId;
method = 'PUT'
}else{
console.log("In Add api")
customerApi = 'https://localhost:44387/api/Customers';
method = 'POST'
}
const myHeader = new Headers({
'Accept':'application/json',
'Content-type':'application/json'
});
fetch(customerApi,{
method:method,
headers:myHeader,
body:JSON.stringify(data)
})
.then(res => res.json())
.then(
(result) => {
this.setState({
users:result,
isAddCustomer:false,
isEditCustomer:false
})
},(error) => {
this.setState({ error });
}
)
}
//Edit customer record
onEditCustomer = customerId => {
//Get ID, name and address
this.setState({
editCustomerId:customerId
});
const customerApi = 'https://localhost:44387/api/Customers/'+customerId;
const myHeader = new Headers({
'Accept':'application/json',
'Content-type':'application/json; charset=utf-8'
});
fetch(customerApi,{
method:'GET',
headers:myHeader
})
.then(res => res.json())
.then(
(result) => {
this.setState({
isEditCustomer:true,
isAddCustomer:false,
singleCustomer:{
customer:result,
isEditCustomer:true
}
})
},(error) => {
this.setState({ error });
}
)
}
//Delete Customer
onDeleteCustomer = customerId => {
const customerApi = 'https://localhost:44387/api/Customers/'+customerId;
const myHeader = new Headers({
'Accept':'application/json',
'Content-type':'application/json; charset=utf-8'
});
fetch(customerApi,{
method:'DELETE',
headers:myHeader
})
.then(res => res.json())
.then(
(result) => {
this.setState({
isDeleteCustomer:false
})
},(error) => {
this.setState({ error });
}
)
}
render() {
let form;
if(this.state.isAddCustomer && !this.state.isEditCustomer){
console.log("Add")
form = <AddCustomer onAddFormSubmit={this.onAddFormSubmit}
isAddCustomer = {this.state.isAddCustomer}
onFormControl = {this.onFormControl}/>
}else if(this.state.isEditCustomer && !this.state.isAddCustomer){
console.log("Edit")
form = <AddCustomer onAddFormSubmit={this.onAddFormSubmit}
singleCustomer = {this.state.singleCustomer}
onFormControl = {this.onFormControl}/>
}else if(this.state.isDeleteCustomer){
console.log("Delete")
console.log(this.state.deleteId)
form = <DeleteRecord onDeleteCustomer={this.onDeleteCustomer}
deleteId = {this.state.deleteId}
/>
}
return (
<div>
{form}
<br/>
<CustomerView
onEditCustomer = {this.onEditCustomer}
onCreate = {this.onCreate}
onDeleteClick = {this.onDeleteClick}/>
</div>
)
}
}
Here is CustomerView.js
import React from 'react';
import { Table, Button } from 'semantic-ui-react';
export default class CustomerView extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
deleteTitle: "customer",
isLoaded: false,
formClose: false,
singleCustomer: [],
users: []
}
}
//fetch data
componentDidMount() {
const customerApi = 'https://localhost:44387/api/Customers';
const myHeader = new Headers();
myHeader.append('Content-type', 'application/json');
myHeader.append('Accept', 'application/json');
myHeader.append('Origin', 'https://localhost:44387');
const options = {
method: 'GET',
myHeader
};
fetch(customerApi, options)
.then(res => res.json())
.then(
(result) => {
this.setState({
users: result,
isLoaded: true
});
},
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
//Delete Customer
onDeleteCustomer = customerId => {
const { users } = this.state;
this.setState({
users: users.filter(customer => customer.customerId !== customerId)
});
const customerApi = 'https://localhost:44387/api/Customers/' + customerId;
const myHeader = new Headers({
'Accept': 'application/json',
'Content-type': 'application/json; charset=utf-8'
});
fetch(customerApi, {
method: 'DELETE',
headers: myHeader
})
.then(res => res.json())
.then(
(result) => {
this.setState({
})
}, (error) => {
this.setState({ error });
}
)
}
render() {
const { users } = this.state;
return (
<div>
<Button color='blue' onClick={() => this.props.onCreate()}>New Customer</Button>
<br/>
<br/>
<Table celled textAlign='center'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>ID</Table.HeaderCell>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Address</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body >
{
users.map(user => (
<Table.Row key={user.customerId}>
<Table.Cell>{user.customerId}</Table.Cell>
<Table.Cell>{user.name}</Table.Cell>
<Table.Cell>{user.address}</Table.Cell>
<Table.Cell>
<Button color='blue' onClick={() =>
this.props.onEditCustomer(user.customerId)}>Edit</Button>
</Table.Cell>
<Table.Cell>
<Button color='red' onClick={() =>
this.props.onDeleteClick(user.customerId)}>Delete</Button>
</Table.Cell>
</Table.Row>
))
}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='5'>
No of Pages
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</div>
)
}
}
Here is AddCustomer.js
import React from 'react';
import { Button, Form, Modal } from 'semantic-ui-react';
export default class AddCustomer extends React.Component {
constructor(props) {
super(props);
this.state = {
showCreateForm: false,
addOrdit:false,
id: "",
name: "",
address: "",
formData: {},
record: {}
}
if (props.isAddCustomer){
this.state.showCreateForm = props.isAddCustomer;
}
else if (props.singleCustomer) {
console.log("Single customer")
console.log(props.singleCustomer)
this.state.id = props.singleCustomer.customer.customerId;
this.state.name = props.singleCustomer.customer.name;
this.state.address = props.singleCustomer.customer.address;
this.state.record = props.singleCustomer.customer;
this.state.showCreateForm = props.singleCustomer.isEditCustomer;
this.state.addOrdit = props.singleCustomer.isEditCustomer;
console.log(this.state.name)
}else if(props.closeForm){
this.state.showCreateForm = props.closeForm;
}
}
handleChangeName = event => {
const value = event.target.value;
this.setState({ name:value });
}
handleChangeAddress = event => {
const value = event.target.value;
this.setState({ address:value });
}
handleSubmit = event => {
event.preventDefault();
if(this.state.addOrdit){
this.setState({
record: {
customerId: this.state.id,
name: this.state.name,
address: this.state.address
}
});
this.props.onAddFormSubmit(this.state.record);
}else{
this.setState({
formData: {
name: this.state.name,
address: this.state.address
}
});
this.props.onAddFormSubmit(this.state.formData);
}
}
//On cancel button click close Create user form
closeCreateForm = () => {
this.setState({ showCreateForm: false })
this.props.onFormControl();
}
//Open Create new Customer form
openCreateCustomer = () => {
this.setState({ showCreateForm: true })
}
render() {
let formTitle;
if (this.state.id !== 0) {
formTitle = "Edit Customer";
} else {
formTitle = "New Customer";
}
return (
<div>
<Modal size='small'
closeOnTriggerMouseLeave={false}
open={this.state.showCreateForm}>
<Modal.Header>
{formTitle}
</Modal.Header>
<Modal.Content>
<Form onSubmit={this.handleSubmit}>
<Form.Field>
<label>Name</label>
<input type="text" placeholder='Name' name="name"
value={this.state.name}
onChange={this.handleChangeName} />
</Form.Field>
<Form.Field>
<label>Address</label>
<input type="text" placeholder='Address' name="address"
value={this.state.address}
onChange={this.handleChangeAddress} />
</Form.Field>
<br />
<Button type='submit' floated='right' color='green'>Create</Button>
<Button floated='right' onClick={this.closeCreateForm}
color='black'>Cancel</Button>
<br />
</Form>
</Modal.Content>
</Modal>
</div>
)
}
}
And last one DeleteRecord.js
import React from 'react';
import { Button, Modal, Icon } from 'semantic-ui-react';
export default class DeleteRecord extends React.Component {
constructor(props) {
super(props);
this.state = {
ID:'',
title: "",
open: false
}
if(props.deleteId){
console.log(props.deleteId)
this.state.ID = props.deleteId.ID;
this.state.title = props.deleteId.title;
this.state.open = props.deleteId.open;
}
}
//On cancel button click close Create user form
closeCreateForm = () => {
console.log("Clicked")
this.setState({ open: false })
}
//Open Create new Customer form
openCreateCustomer = () => {
this.setState({ open: true })
}
render() {
const title = "Delete " + this.state.title;
return (
<div>
<Modal size='small'
closeOnTriggerMouseLeave={false}
open={this.state.open}>
<Modal.Header>
{title}
</Modal.Header>
<Modal.Content>
<br />
Are you sure?
<br />
<br />
<Button floated='right' icon labelPosition='right' color='red'
value='true'
onClick={() => this.props.onDeleteCustomer(this.state.ID)}
>
<Icon name='close' />
Delete
</Button>
<Button floated='right' color='black'
value='false'
onClick={this.closeCreateForm}
>Cancel</Button>
<br />
<br />
</Modal.Content>
</Modal>
</div>
)
}
}
Try using mobx for managing state variables and axios for making calls to API this will resolve your problem.
sample example code for using mobx
import { observable, computed } from "mobx"
class OrderLine {
#observable price = 0
#observable amount = 1
#computed get total() {
return this.price * this.amount;
}
}
now you can import OrderLine class in your Js and you can use and manage the state of price, amount dynamically for rendering the UI
Go through below link
https://mobx.js.org/README.html

Reactjs displays error users.map is not a function

I am getting the following error in my React application:
users.map is not a function
I have tried many solutions posted on Stack Overflow but it does not seems to solve my issue.
I used the code below to submit a filename and it works fine. Here is my problem. Each time i click on submit button, i
want to display a JSON data from the backend in a succession (For Instance If I submit form 3 times, I need to have 3 records of JSON data showed).
Here is the sample of JSON:
{"filename":"macofile","message":"success","uid":"20"}
To this effect I have set the following line of code in the Axios Post response
this.setState({
users: res.data,
loading: false,
});
I have also tried
users: res
or
users.push(res.data);
This is my code:
import React, { Component } from "react";
import axios, { post } from "axios";
class FilePage extends React.Component {
constructor(props) {
super(props);
this.state = {
value: "",
filename: "",
loading: false,
users: [],
error: null
};
this.handleChange = this.handleChange.bind(this);
}
_handleSubmit(e) {
e.preventDefault();
//send it as form data
const formData = new FormData();
formData.append("filename", this.state.filename);
//alert(this.state.filename);
this.setState({ loading: true }, () => {
axios
.post("http://localhost/apidb_react/up.php", formData)
.then(res => {
this.setState({
users: res.data,
loading: false
});
})
.catch(err => {
console.log(err.message);
});
});
}
// handle form submission
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
render() {
const { loading, users, error } = this.state;
return (
<div>
<form onSubmit={e => this._handleSubmit(e)}>
<b>filename:</b>
<input
tyle="text"
className="form-control"
value={this.state.filename}
name="filename"
onChange={this.handleChange}
/>
<button
className="submitButton"
type="submit"
onClick={e => this._handleSubmit(e)}
>
submit
</button>
</form>
<React.Fragment>
<h3>Display Data each time record is submitted</h3>
{error ? <p>{error.message}</p> : null}
{!loading ? (
users.map(user => {
const { filename, message, uid } = user;
return (
<div key={uid}>
<p>Userid: {uid}</p>
<p>File Name: {filename}</p>
<p>Message: {message}</p>
<hr />
</div>
);
})
) : (
<h3>Loading...</h3>
)}
</React.Fragment>
</div>
);
}
}
Your res.data seems to be an object rather than an array -> {"filename":"macofile","message":"success","uid":"20"}. So, you will need to loop through the object by taking an array for eg:
Object.keys(users).map(key => console.log(users[key]))

Update Apollo store after filtered query

I have a list of items which can be filtered out using certain criteria. Whenever i perform a search, i want to grab a filtered item and update its content which seems to update the apollo store correctly, but for some reason changes are not being shown. Perhaps the componentWillReceiveProps lifecycle method is not being fired and i need to implement it by myself?
I tried updating the store manually using "update" after the mutation but it wont work also.
This is my code so far:
ClientList.js
class ClientList extends Component {
constructor(props) {
super(props);
this.state = {
hasMoreItems: true,
loading: false,
clients: [],
searchText: ''
}
}
_executeSearch = async () => {
const { searchText } = this.state;
this.setState({ loading: true });
const result = await this.props.client.query({
query: ALL_CLIENTS_QUERY,
variables: { searchText },
fetchPolicy: 'network-only'
})
this.setState({
clients: result.data.allClients,
loading: false
});
}
render() {
let { allClients, loading, fetchMore } = this.props.data;
const { hasMoreItems, clients, searchText } = this.state;
if (clients.length > 0) {
allClients = clients;
loading = this.state.loading;
}
return (
<section>
<h1 className="text-center">Clients</h1>
<InputGroup>
<InputGroupButton>
<Button onClick={() => this._executeSearch()}>I'm a button</Button>
</InputGroupButton>
<Input
onChange={(e) => this.setState({ searchText: e.target.value })}
placeholder="Search by social or comercial name"
/>
</InputGroup>
{loading ?
<div className="text-center mt-4">
<i className="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>
</div>
: <div className="mt-3">
{allClients.map(client =>
<div key={`client-${client.id}`} className="client-content">
<Link to={`/clients/${client.id}`}>
<h1 className="mb-1">
{client.socialName}
<small className="text-muted ml-3">{client.comercialName}</small>
</h1>
</Link>
</div>
})
</div>
</section>
);
};
}
export default withApollo(graphql(ALL_CLIENTS_QUERY)(ClientList));
ClientEdit.js
class ClientEdit extends Component {
onSubmit = async (e) => {
e.preventDefault();
this.setState({ loading: true });
const payload = {
id: this.props.match.params.id,
rfc: this.state.rfc,
socialName: this.state.socialName,
legalRepresentative: this.state.legalRepresentative,
comercialName: this.state.comercialName
}
// Mutation updates the store but doesnt show results
const resp = await this.props.mutate({
variables: payload,
update: (store, { data: { updateClient } }) => {
// Tried updating but it doesnt show changes also;
}
});
}
}
export default compose(
graphql(GET_CLIENT_QUERY, {
options: props => ({
variables: {
id: props.match.params.id
}
})
}),
graphql(UPDATE_CLIENT_MUTATION)
)(ClientEdit);
better if we check that the data is ready and we can render it out , and when data still fetching so no render associated with that apollo data object should be done:
render(){
const {loading} = this.props.data;
if(loading) {return <div>Loading...</div>}
return (
...
)
I manage to fix this using the componentWillReceiveProps lifecycle method. I dont know if this is a bug or maybe there is another solution;
componentWillReceiveProps(newProps) {
const { allClients, loading } = newProps.data;
if (!loading) {
const clients = _.intersectionBy(allClients, this.state.clients, 'id');
this.setState({ clients });
}
}

React setState fetch API

I am starting to learn React and creating my second project at the moment. I am trying to usi MovieDb API to create a movie search app. Everything is fine when I get the initial list of movies. But onClick on each of the list items I want to show the details of each movie. I have created a few apps like this using vanilla JS and traditional XHR call. This time I am using fetch API which seems straightforward ans simply to use, however when I map through response data to get id of each movie in order to retrieve details separately for each of them I get the full list of details for all the items, which is not the desired effect. I put the list of objects into an array, because after setState in map I was only getting the details for the last element. I know that I am probably doing something wrong within the API call but it might as well be my whole REACT code. I would appreciate any help.
My code
App.js
import React, { Component } from 'react';
import SearchInput from './Components/SearchInput'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state =
{
value: '',
showComponent: false,
results: [],
images: {},
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleOnChange = this.handleOnChange.bind(this);
this.getImages = this.getImages.bind(this);
this.getData = this.getData.bind(this);
}
ComponentWillMount() {
this.getImages();
this.getData();
}
getImages(d) {
let request = 'https://api.themoviedb.org/3/configuration?api_key=70790634913a5fad270423eb23e97259'
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
this.setState({
images: data.images
});
});
}
getData() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.state.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
this.setState({
results: data.results
});
});
}
handleOnChange(e) {
this.setState({value: e.target.value})
}
handleSubmit(e) {
e.preventDefault();
this.getImages();
this.setState({showComponent: true});
this.getData();
}
render() {
return (
<SearchInput handleSubmit={this.handleSubmit} handleOnChange={this.handleOnChange} results={this.state.results} images={this.state.images} value={this.state.value} showComponent={this.state.showComponent}/>
);
}
}
export default App;
SearchInput.js
import React, {Component} from 'react';
import MoviesList from './MoviesList';
class SearchInput extends Component {
render() {
return(
<div className='container'>
<form id='search-form' onSubmit={this.props.handleSubmit}>
<input value={this.props.value} onChange={this.props.handleOnChange} type='text' placeholder='Search movies, tv shows...' name='search-field' id='search-field' />
<button type='submit'>Search</button>
</form>
<ul>
{this.props.showComponent ?
<MoviesList value={this.props.value} results={this.props.results} images={this.props.images}/> : null
}
</ul>
</div>
)
}
}
export default SearchInput;
This is the component where I try to fetch details data
MovieList.js
import React, { Component } from 'react';
import MovieDetails from './MovieDetails';
let details = [];
class MoviesList extends Component {
constructor(props) {
super(props);
this.state = {
showComponent: false,
details: []
}
this.showDetails = this.showDetails.bind(this);
this.getDetails = this.getDetails.bind(this);
}
componentDidMount() {
this.getDetails();
}
getDetails() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.props.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
data.results.forEach((result, i) => {
let url = 'https://api.themoviedb.org/3/movie/'+ result.id +'?api_key=70790634913a5fad270423eb23e97259&append_to_response=videos,images';
return fetch(url)
.then((response) => {
return response.json();
}).then((data) => {
details.push(data)
this.setState({details: details});
});
});
console.log(details);
});
}
showDetails(id) {
this.setState({showComponent: true}, () => {
console.log(this.state.details)
});
console.log(this.props.results)
}
render() {
let results;
let images = this.props.images;
results = this.props.results.map((result, index) => {
return(
<li ref={result.id} id={result.id} key={result.id} onClick={this.showDetails}>
{result.title}{result.id}
<img src={images.base_url +`${images.poster_sizes?images.poster_sizes[0]: 'err'}` + result.backdrop_path} alt=''/>
</li>
)
});
return (
<div>
{results}
<div>
{this.state.showComponent ? <MovieDetails details={this.state.details} results={this.props.results}/> : null}
</div>
</div>
)
}
}
export default MoviesList;
MovieDetails.js
import React, { Component } from 'react';
class MovieDetails extends Component {
render() {
let details;
details = this.props.details.map((detail,index) => {
if (this.props.results[index].id === detail.id) {
return(
<div key={detail.id}>
{this.props.results[index].id} {detail.id}
</div>
)} else {
console.log('err')
}
});
return(
<ul>
{details}
</ul>
)
}
}
export default MovieDetails;
Theres a lot going on here...
//Here you would attach an onclick listener and would fire your "get details about this specific movie function" sending through either, the id, or full result if you wish.
//Then you getDetails, would need to take an argument, (the id) which you could use to fetch one movie.
getDetails(id){
fetch(id)
displayresults, profit
}
results = this.props.results.map((result, index) => {
return(
<li onClick={() => this.getDetails(result.id) ref={result.id} id={result.id} key={result.id} onClick={this.showDetails}>
{result.title}{result.id}
<img src={images.base_url +`${images.poster_sizes?images.poster_sizes[0]: 'err'}` + result.backdrop_path} alt=''/>
</li>
)
});
Thanks for all the answers but I have actually maanged to sort it out with a bit of help from a friend. In my MovieList I returned a new Component called Movie for each component and there I make a call to API fro movie details using each of the movie details from my map function in MovieList component
Movielist
import React, { Component } from 'react';
import Movie from './Movie';
class MoviesList extends Component {
render() {
let results;
if(this.props.results) {
results = this.props.results.map((result, index) => {
return(
<Movie key={result.id} result={result} images={this.props.images}/>
)
});
}
return (
<div>
{results}
</div>
)
}
}
export default MoviesList;
Movie.js
import React, { Component } from 'react';
import MovieDetails from './MovieDetails';
class Movie extends Component {
constructor(props) {
super(props);
this.state = {
showComponent: false,
details: []
}
this.showDetails = this.showDetails.bind(this);
this.getDetails = this.getDetails.bind(this);
}
componentDidMount() {
this.getDetails();
}
getDetails() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.props.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
let url = 'https://api.themoviedb.org/3/movie/'+ this.props.result.id +'?api_key=70790634913a5fad270423eb23e97259&append_to_response=videos,images';
return fetch(url)
}).then((response) => {
return response.json();
}).then((data) => {
this.setState({details: data});
});
}
showDetails(id) {
this.setState({showComponent: true}, () => {
console.log(this.state.details)
});
}
render() {
return(
<li ref={this.props.result.id} id={this.props.result.id} key={this.props.result.id} onClick={this.showDetails}>
{this.props.result.title}
<img src={this.props.images.base_url +`${this.props.images.poster_sizes?this.props.images.poster_sizes[0]: 'err'}` + this.props.result.backdrop_path} alt=''/>
{this.state.showComponent ? <MovieDetails details={this.state.details}/> : null}
</li>
)
}
}
export default Movie;

Resources