I'm new to flux. I'm struggling past 10 hrs to resolve this issues. I have created one sample todo app. Initially i want to load some data from server. But i don't know how to get that data. While i'm clicking the button that time i'm able to get the data. Please someone help me out from this problem. Because i'm trying to finish this one from long time.
My sample code,
App.js
var React = require('react');
import * as TodoActions from "./js/Actions";
import TodoStore from "./js/stores/EventLists";
export class EventListing extends React.Component {
constructor() {
super();
this.getTodos = this.getTodos.bind(this);
this.state = {
todos: TodoStore.getAll(),
};
}
componentWillMount() {
TodoStore.on("change", this.getTodos);
}
componentWillUnmount() {
TodoStore.removeListener("change", this.getTodos);
}
getTodos() {
this.setState({
todos: TodoStore.getAll(),
});
}
reloadTodos() {
TodoActions.reloadTodos();
}
render() {
var List = this.state.todos.map(function(el, i){
return <li key={i}>
<div>{el.STA_NAME}</div>
</li>;
});
return (
<div className="listing">
<button onClick={this.reloadTodos.bind(this)}>Reload!</button>
<ul>
{List}
</ul>
</div>
);
}
}
var Events = React.createClass({
render:function(){
return (<div>
<EventListing />
</div>);
}
});
module.exports = Events;
Store.js
import EventEmitter from 'events';
import dispatcher from "../dispatcher"
class EventLists extends EventEmitter {
constructor(){
super();
this.todos = [{}];
}
createTodo(text) {
const id = Date.now();
this.todos.push({
id,
text,
complete: false,
});
this.emit("change");
}
getAll() {
return this.todos;
}
handleActions(action) {
switch(action.type) {
case "CREATE_TODO": {
this.createTodo(action.text);
break;
}
case "RECEIVE_TODOS": {
this.todos = action.todos;
this.emit("change");
break;
}
}
}
};
const eventLists = new EventLists;
dispatcher.register(eventLists.handleActions.bind(eventLists));
export default eventLists;
Action.js
import dispatcher from "./dispatcher";
export function createTodo(text) {
dispatcher.dispatch({
type: "CREATE_TODO",
text,
});
}
export function deleteTodo(id) {
dispatcher.dispatch({
type: "DELETE_TODO",
id,
});
}
export function reloadTodos() {
var loadData;
$.ajax({
url:url,
type:'GET',
contentType: 'application/json; charset=UTF-8',
dataType:'json',
success:function(data) {
loadData = data;
}.bind(this)
});
dispatcher.dispatch({type: "FETCH_TODOS"});
setTimeout(() => {
console.log(loadData);
dispatcher.dispatch({type: "RECEIVE_TODOS", todos: loadData});
}, 1000);
}
Dispatcher.js
import { Dispatcher } from "flux";
export default new Dispatcher;
I've tried your code and the only thing that you need to change is on Action.js.
Because of the ajax call, you have to wait until the response comeback and user the dispatcher before ajar call with event FETCH_TODOS
and on success function with event RECEIVE_TODOS
.
Timeout is a bad idea to wait an ajax response.
export function reloadTodos() {
dispatcher.dispatch({type: "FETCH_TODOS"});
var loadData;
$.ajax({
url:url,
type:'GET',
contentType: 'application/json; charset=UTF-8',
dataType:'json',
success:function(data) {
loadData = data;
dispatcher.dispatch({type: "RECEIVE_TODOS", todos: loadData});
}
});
}
EDITTED
Ok now I understand a little more
please add this method to Action.js
export function loadData() {
dispatcher.dispatch({ type: "FETCH_TODOS" });
$.ajax({
url: "https://jsonplaceholder.typicode.com/todos/",
type: 'GET',
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
success: function(response) {
dispatcher.dispatch({ type: "RECEIVE_TODOS", todos: response });
}
});
}
and call it on your app.js on the constructor method so you can have the data initialized at the very begining
export class EventListing extends React.Component {
constructor() {
super();
this.getTodos = this.getTodos.bind(this);
this.state = {
todos: TodoStore.getAll(),
};
TodoActions.loadData();
}
Note that because of flux you will get the data correctly when RECEIVE_TODOS
be handled