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 "-".
Related
In my react app I want to send state to the next path through the history.location.state and history.location.pathname
In my case, it has to push successfully and also showing in history but when I console.log(this.props.history) in the child page showing undefined.
MyComponent Code
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
class MyComponent extends Component {
state = {
cart: {
1:{
icon: "URL"
id: 1
quantity: 1
title: "item1"
}
2:{
icon: "URL"
id: 2
quantity: 1
title: "item2"
}
}
}
submitHandler = (event) => {
event.preventDefault();
let data = {};
for (let key in this.state.cart) {
data[key] = this.state.cart[key]
}
console.log("data=",data);
this.props.history.push({
pathname: "/result",
state: { data: data }
});
}
render(){
return(
<div >
<button onClick={this.submitHandler}>CONTINUE</button>
</div>
)
}
}
export default withRouter(MyComponent);
Result Component
import React, { Component } from 'react';
class Result extends Component {
render() {
console.log("ss=",this.props.history);
return(<div>Result</div>)
}
export default Result;
In Console
Route
<Route path="/result" component={Result} />
As shown in the above img in history->location->state is push fine.
But when I console log to this.props showing undefined.
Also I already use withRouter hoc of react-router-dom in export
Suggest me a solution to this?
May be you are called wrong path. its working and the state variable available on this.props.location not a this.props.history;
Codesanbox example
I'm trying to render the following the 'dogName' value of the following array to the browser, but it's coming up as 'undefined':
[
{
"id": 1,
"dogName": "bruce"
},
{
"id": 2,
"dogName": "borker"
},
{
"id": 3,
"dogName": "henry"
}
]
So, first of all, the data is pulled from a database and set in state in the parent component, where's it's passed as props to the child component 'DogNameList' (which I've trimmed down to just the relevant bits):
import React from 'react';
import './styles.css'
import DogList from './DogList'
import Dogue from './Dogue'
import axios from 'axios'
import DogNameList from './DogNameList'
class App extends React.Component {
constructor(){
super()
this.state = {
**dogName:[]**
}
}
componentDidMount() {
axios.get('http://localhost:3000/dogs')
.then(res => {
this.setState({
**dogName:res.data**
})
})
.catch(error => {
console.log(error)
})
}
render() {
return (
<div>
<DogNameList **names = {this.state.dogName}**/>
<Dogue/>
</div>
);
}
}
export default App;
In DogNameList, the data is mapped over and then passed as props to the 'Dogue' component (stupid names, I know, but this is a personal project):
import React from 'react'
import Dogue from './Dogue'
const DogNameList = (props) => {
return(
<div>
{
props.names.map(name => {
console.log(name.dogName)
return <Dogue name = {name} key ={name.id}/>
})
}
</div>
)
}
export default DogNameList
finally, it's supposed to be rendered to the browser via the 'Dogue' component:
import React from 'react'
import axios from 'axios'
class Dogue extends React.Component {
constructor(props){
super(props)
this.state = {
}
}
render(){
return (
<div>
<img className = 'img' src = {this.props.dogList}/>
<br/>
<form className = 'form'>
<input type = 'text' placeholder = 'Enter dog name'/>
<br/>
<button>Submit</button>
</form>
**<h2>dog name: {this.props.name}</h2>**
</div>
)
}
}
export default Dogue
Any ideas why it's not working? I console logged the following and it returned the list of names (not as strings, I should add):
props.names.map(name => {
console.log(name.dogName)
First of all, replace this
<h2>dog name: {this.props.name}</h2>
with this
<h2>dog name: {this.props.name.dogName}</h2>
because you are creating a component with object, so name property actually holds the object, not the name property of the object.
return <Dogue name = {name} key ={name.id}/>
You also don't declare somewhere this property
{this.props.dogList}
Also to handle the undefined error messages, do this
{this.state.dogName && <DogNameList names ={this.state.dogName}/>}
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 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?
I'm using slack API to retrieve messages from bot app (like trello in slack.com). I used this API https://slack.com/api/im.history. But my goal, is to get messages from that bot app in real time to my application without reloading page. I already read the RTM API docs, and also The events API. I didn't figure out how to do so. What should I do ?
Here is server/main.js :
import { Meteor } from 'meteor/meteor';
import { HTTP } from 'meteor/http';
import '../imports/api/messages.js';
Meteor.startup(() => {
Meteor.methods({
checkSlack() {
this.unblock();
try {
var result = HTTP.call('GET','https://slack.com/api/im.history', {
params: {
token: 'xxxx-xxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx',
channel: 'xxxxxxxxxx'
}
});
return result.data.messages;
} catch (error) {
// Got a network error, timeout, or HTTP error in the 400 or 500 range.
return error.message;
}
}
});
});
imports/api/messages.js:
import { Mongo } from 'meteor/mongo';
export const Messages = new Mongo.Collection('messages');
if (Meteor.isServer) {
// This code only runs on the server
Meteor.publish('messages', function messagesPublication() {
return Messages.find();
});
}
imports/ui/Message.jsx:
import React, { Component, PropTypes } from 'react';
export default class Message extends Component {
render() {
return (
<li>{this.props.message.text}</li>
);
}
}
Message.propTypes = {
message: PropTypes.object.isRequired,
};
imports/ui/App.jsx:
import React, { Component, PropTypes } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import { Messages } from '../api/messages.js';
import Message from './Message.jsx';
const _ = require('lodash');
// App component - represents the whole app
class App extends Component {
constructor(props){
super(props);
this.state = {
messages: [],
};
this.renderMessages = this.renderMessages.bind(this);
this.getMessages = this.getMessages.bind(this);
this.saveMessages = this.saveMessages.bind(this);
}
componentDidMount() {
this.getMessages();
}
getMessages() {
const handle = this;
Meteor.call('checkSlack',function(err, response) {
if(err){
console.log('error');
}
else {
handle.setState({
messages: response,
});
}
});
};
renderMessages() {
const messages = Messages.find({}).fetch();
return messages.map((message, index) => (
<Message key={index} message={message} />
));
}
saveMessages(){
const messages = this.state.messages;
const msgs = Messages.find({}).fetch();
var addedMsgs = _.differenceBy(messages,msgs, 'ts');
_.map(addedMsgs, (message) =>
Messages.insert(message)
);
}
render() {
return (
<div className="container">
<header>
<h1>Messages List</h1>
</header>
<button onClick={this.saveMessages}>Save</button>
{this.renderMessages()}
</div>
);
}
}
App.propTypes = {
messages: PropTypes.array.isRequired,
};
export default createContainer(() => {
Meteor.subscribe('messages');
return {
messages: Messages.find({}).fetch(),
};
}, App);
client/main.jsx:
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import App from '../imports/ui/App.jsx';
Meteor.startup(() => {
render(<App />, document.getElementById('render-target'));
});
client/main.html:
<head>
<title>App</title>
</head>
<body>
<div id="render-target"></div>
</body>
If you can get the Slack events coming through from the API, to a Meteor server, simply insert them into a Mongo collection, and then set up your Meteor client to subscribe to the database, and you will have a real time feed to your UI
UPDATE
Thanks for possting your code, now I can see what's going on.
1) In your server code you are doing this:
Meteor.startup(() => {
Meteor.methods({
It probably works OK, but these are independent things. Meteor methods often lives in another file, and is just used to declare your methods.
2) You only save the messages to the collection from the UI. They need to be inserted when you get them in the server method - then your publication and subscription will work
3) Remove the call to checkSlack from componentDidMount, and put it in the server startup.
4) Your http request to slack will only retrieve the history, you need to get more sophisticated here. Read https://api.slack.com/rtm for how you can open a socket and get a real time feed