I am new to React JS and creating an app which diplays campaigns and their details. I am using Firebase as database.
I managed to display the list of campaigns and its details. When user clicks on each campaing number it links to the preview page of this campaign:
<th><Link to={"/Preview/"+cam.id} key={cam.id}>{cam.cnumber}</Link></th>
On the Preview page the id in URL is correct and console.log(camp)(After setState) gives object with all the data but it doesn't render the list in a DOM. Anyone can help with this one please?
Console.log(cam) from renderOptions() prints:
{id: "L0000000", cnumber: undefined, adnumber: undefined, weekno: undefined, title: undefined, …}
Here is my code:
import React, { Component } from 'react';
import firebase from './firebase';
import banner from './banner.jpg';
import Header from './Header';
import { key } from "firebase-key";
class Preview extends Component {
constructor(props) {
super(props);
this.state = {
camp:[],
};
this.renderOptions = this.renderOptions.bind(this);
}
componentDidMount() {
const projectId = this.props.params.key;
var itemsRef= firebase.database().ref('campaigns/'+ projectId);
itemsRef.on('value', (snapshot) => {
let camp = snapshot.val();
let newState = [];
newState.push({
id:projectId,
cnumber: projectId.cnumber,
adnumber:projectId.adnumber,
weekno:projectId.weekno,
title:projectId.title,
brand:projectId.brand,
advertiser:projectId.advertiser
});
this.setState({
camp:newState
});
console.log(camp);
});
}
renderOptions(e) {
return this.state.camp.map((cam) => {
console.log(cam);
return(
<ul key={cam.id}>
<li>{cam.cnumber}</li>
<li>{cam.weekno}</li>
<li>{cam.adnumber}</li>
<li>{cam.title}</li>
<li>{cam.brand}</li>
<li>{cam.advertiser}</li>
</ul>
);
});
}
render(){
return (
<div>
<Header />
{this.renderOptions()}
</div>
);
}
}
export default Preview;
When you are doing newState.push at itemsRef.on('value', ...), you seem to be using projectId object to fill in the informations. Shouldn't you be using the camp object that you parsed through from snapshot?
Related
Good day to all!
I have this situation: I use Apollo client to get data from a GraphQL API endpoint in the parent class component in React. I pass this data to the child class component. The first time everything works fine but after a page refresh the data in the child component becomes undefined and the app crashes.
Here is the representation of the situation:
The ParentComponent
import React, { Component } from 'react'
import { gql } from "apollo-boost";
import {graphql} from 'react-apollo';
import ChildComponent from './ChildComponent'
const getProducts = gql`
{
category {
products {
id
name
gallery
}
}
}
`
class ParentComponent extends Component {
constructor(props) {
super(props)
this.state = {
products: []
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
products: [...this.props.data.category.products]
})
}, 1000)
}
render () {
let products = this.state.products;
return (
<div><ChildComponent theProducts = {products}/></div>
)
}
}
export default graphql(getProducts)(ParentComponent);
The ChildComponent
import React, { Component } from 'react'
class ChildComponent extends Component {
constructor(props) {
super(props)
this.state = {
products: this.props.theProducts
}
}
render () {
let item = this.state.products.find(each => each.id === id);
return (
<div>
<ul>
<li>{item.name}</li>
<li><img src= {item.gallery[0]} alt="product"></img></li>
</ul>
</div>
)
}
}
export default ChildComponent;
So, when the app starts everything seems to work fine. But if I refresh the page it throws an error and says that name is undefined, gallery is undefined. It is clear that the data is not coming through to the ChildComponent. Is there a way to make sure that the data comes in at any time?
Thank you in advance.
You use theProducts in the ChildComponent but you pass theProduct from ParentComponent . And state product also has the same error. Just update to theProducts and product
I am building a site just like stackoverflow.com. I want my home page to display top questions. For that, I have sample questions on the backed. Now, I want to display only the question and tags from the questions array.
The code is in the image
I have made axios connection for that:
const instance = axios.create({
baseURL: "https://2w2knta9ag.execute-api.ap-south-1.amazonaws.com/dev", });
instance.defaults.headers.post["Content-Type"] = "application/json";
To connect it, I wrote the command: instance.get("/questions)
Now, how do I display only the question and tags??
EDIT:
On using the code given bellow, my js file now becomes:
import React from 'react';
import instance from '../../api';
class QuestionList extends React {
componentDidMount() {
instance
.get("/questions")
.then((res) => {
this.setState({ data: res.data });
});
}
render () {
const { data } = this.state;
return <div>
{
data && data.map(d => {
return <div>question: {d.question}, tags: {d.tags}</div>;
})
}
</div>
}
}
export default QuestionList;
But, this is just making my site in a loading state, and it gets hanged!!
If I understood correctly, you want to get an array only with the tags and the question. if so, you can use Array.prototype.map for this
const questions = result.map(({ question, tags }) => ({ question, tags }))
First you export the axios instance so that it can be used from other components.
Now you can send the api request in componentDidMount and update your component's state with the data.
And in render function, you just get the value from state and display.
If you are new to react, learn React Hooks and know that componentDidMount method is the best place to send api requests.
For Example:
import React from 'react';
import instance from '../../api';
class QuestionList extends React.Component {
constructor() {
super();
this.state = {
data: [],
};
}
componentDidMount() {
instance.get('/questions').then((res) => {
this.setState({ data: res.data });
});
}
render() {
const { data } = this.state;
return (
<div>
{data &&
data.map((d) => {
return (
<div>
question: {d.question}, tags: {d.tags}
</div>
);
})}
</div>
);
}
}
export default QuestionList;
Guys Kindly i need your help. I am trying to fetch data from an Api and display it in the dom. I can see the data in the console but when i try to return data it shows a blank page and no errors. Below is my code.
App.js file
import React from "react";
import "./App.css";
import Movieapp from "./Movieapp";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: [],
date: [],
image: []
};
}
componentDidMount() {
fetch(`https://yts.mx/api/v2/list_movies.json?quality=3D`)
.then(res => res.json())
.then(data => {
console.log(data.data);
this.setState = {
title: data.data.movies[0].title,
date: data.data.movies[0].date_uploaded,
image: data.data.movies[0].background_image
};
});
}
render() {
return (
<div className="App">
<Movieapp
title={this.state.title}
date={this.state.date}
image={this.state.image}
/>
</div>
);
}
}
export default App;
Movieapp.js file
import React from "react";
const Movieapp = props => {
return (
<div>
<h1>{props.title}</h1>
<h1>{props.date}</h1>
<div>{props.image}</div>
</div>
);
};
export default Movieapp;
this.setState is a function, not a property. You have to use it properly:
this.setState({
title: data.data.movies[0].title,
date: data.data.movies[0].date_uploaded,
image: data.data.movies[0].background_image
});
Also, even though I guess you are just trying things our, there are few things to be aware of:
movies[0] can be undefined
You are getting multiple movies but showing only one. It's probably better to just save the whole data array in the state and iterate over the results in the render method
I'm new to TypeScript and reacjs.
When I want to connect React-Typescript with SharePoint online for local development I always receive following error
Type error: Property 'listInformation' does not exist on type 'Readonly<{}>'. TS2339
The property listInformation should not exist but it does. The following code is what I already have. When I try this on a React app without TypeScript there is no problem for running this code.
import React, { Component, Props } from 'react';
import { initializeIcons } from '#uifabric/icons';
import { NavHeader } from './NavHeader';
import { Navigation } from './Navigation';
import { DetailsList, IColumn } from 'office-ui-fabric-react';
initializeIcons();
class Templates extends Component{
constructor(props: {}) {
super(props);
this.state = {
listInformation:[{
Title: '',
DocumentSetDescription: '',
OData__UIVersionString:'',
Type_x0020_of_x0020_Template:'',
Functional_x0020_area:'',
ContentTypeId:''}
]
};
}
componentDidMount() {
// Custom function to retrieve the list info
this.GetListInfo();
}
GetListInfo(){
var reactHandler = this;
var request = new XMLHttpRequest();
request.open('GET', "/_api/web/lists/getbytitle('Templates')/items", true);
request.setRequestHeader("Accept","application/json");
//this callback gets called when the server responds to the ajax call
request.onreadystatechange = function(){
if (request.readyState === 4 && request.status === 200){
var result = JSON.parse(request.responseText);
reactHandler.setState({
listInformation: result.value
});
}
else if (request.readyState === 4 && request.status !== 200){
console.log('Error in retrieving data!');
}
};
request.send();
}
public render() {
this.state.listInformation.map(function(info,key){
if(info.ContentTypeId === '0x0120D52000C935C192A6B8E84F80068B394AAEF962'){
let listInfo = [{Name: info.Title , Description: info.DocumentSetDescription, Version: info.OData__UIVersionString, Type_of_template: info.Type_x0020_of_x0020_Template, Functional_area: info.Functional_x0020_area}]
}
})
return (
<div>
<div>
<NavHeader />
</div>
<div>
<Navigation />
</div>
<div>
<h1>TEMPLATES</h1>
<DetailsList items={listInfo} columns={columns}/>
</div>
</div>
);
}
}
export default Templates;
I work with following site as an example https://www.c-sharpcorner.com/article/retrieve-and-display-sharepoint-list-items-using-rest-api-and-reactjs/
Thanks for helping me out with this.
You have to declare the state as an interface in typescript.
export interface MyState{
listInformation: any[];
}
class Templates extends Component<any, MyState>{
constructor(props: {}) {
super(props);
this.state = {
listInformation:[{
Title: '',
DocumentSetDescription: '',
OData__UIVersionString:'',
Type_x0020_of_x0020_Template:'',
Functional_x0020_area:'',
ContentTypeId:''}
]
};
}
You can also create an interface for props that you may need to export - which can be exported along side state as <MyProps, MyState>. You might also need to declare each property inside your state object within the interface. Not entirely sure.
I'm trying to return a venue's description using React.JS and the Foursquare API.
I understand that you need to pass the venue's ID to retrieve any additional venue information and currently I'm able to pull a certain amount of venues but none of the descriptions are appearing. Attached below is my current app.js file (with authentication details X'd out) and a screenshot of what I'm seeing in my browser.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './App.css';
var foursquare = require('react-foursquare')({
clientID: 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
clientSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
});
var params = {
"near": "Wilkes-Barre, PA",
"categoryId": '4d4b7105d754a06374d81259',
"radius":"250"
};
export default class FoursquareDemo extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
place: null
};
}
componentDidMount() {
foursquare.venues.getVenues(params)
.then(res=> {
this.setState({ items: res.response.venues });
});
}
render() {
return (
<div>
<div>Items:</div>
{ this.state.items.map(item=> { return <div key={item.id}>{item.name} - {item.location.city} - {foursquare.venues.getVenue(item.id).description}</div>}) }
<br />
</div>
)
}
}
ReactDOM.render(
<FoursquareDemo />,
document.getElementById('root')
);
Browser Screenshot:
Ideally, I'd like to pull the description in after the venue name and the hyphen "-".