I created an <Agenda /> component with the code below, but the agenda show an spin loading forever. I created the project with create-react-native-app.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Facebook, WebBrowser } from 'expo';
import { Linking } from 'react-native';
import { Card, CardSection, Button } from './common';
import { loginWithFacebook } from '../actions';
import { Agenda } from 'react-native-calendars';
@connect(null, { loginWithFacebook })
class LoginStudent extends Component {
static navigationOptions = {
title: 'Login Student',
};
render() {
return (
<Agenda
items={{'2012-05-22': [{text: 'item 1 - any js object'}],
'2012-05-23': [{text: 'item 2 - any js object'}],
'2012-05-24': [],
'2012-05-25': [{text: 'item 3 - any js object'}],
}}
loadItemsForMonth={(mongh) => {console.log('trigger items loading')}}
onDayPress={(day)=>{console.log('day pressed')}}
selected={'2012-05-16'}
renderItem={item => <View />}
renderDay={(day, item) => <View />}
renderEmptyDate={() => <View />}
rowHasChanged={(r1, r2) => (r1.text !== r2.text)}
hideKnob={true}
theme={{}}
style={{}}
/>
);
}
}
export default LoginStudent;
Hi, that is because probably today is selected and there is no value for today in items map. If there is no item for the day it is being interpreted as still being loaded
Is that the expected behavior or it should show an empty page of the agenda?
I just used the example in the README.md and expected it will work.
@ercpereda Did you find a solution? I am having the same issue.
Thanks!
@ercpereda the solution is to always have value provided in items map for selected day
Ok Thanks!
@tautvilas I going to get my items map from an async call. I wish to show the spinner while the data is being loaded, but hide it when the results come even if the result does not have values for the selected day.
I did suggest that every day should be rendered empty by default here, this way it would work straight out of the box without the need of any data to be passed into the component.
That can be considered, but this would introduce breaking change for our current agenda usecases
Perhaps it could be worthwhile having this as an option? That way you could satisfy both usecases.
Yes, adding something like dayLoading={false} can be done, but by default it would be true. And maybe default can be changed to false in the future.
I think that could be a good solution for avoiding breaking changes and support the async behavior of the calendar.
i have problem that "loadItemsForMonth" function load twice, i've added empty value for empty days, but first time it loaded ok, then the second time it loading forever until i click day to load data again.
@binhluong2012 please compare your solution to example demo and check if you can reproduce the problem in example too
@tautvilas i've used the same agenda example code in this link https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js , just remove "//" at row 55.

It's auto loading default date ( today), then it loading date from 1 month before. My code
loadItems (day) {
console.log('loading data for ' + day.dateString ) }
Hi, sorry, can you clarify the problem? Do I understand correctly that the problem is that load method is called twice on init? You expect it to be called just with today?
@tautvilas
Yes. Now it loading twice on init then it showing spin loading forever.
Yep, but example does not show spin loading forever, right? Maybe when loading for 2017-05-12 is requested you only return items for 05 month. Each loading should re-create the items object with current items and newly loaded items so that it contains all data
@tautvilas So I should pass items object that has empty array to all days of the year that dont have any items to agenda?! That is weird solutions o.O I think the loader should be controlled by coder and not by library
You can track visible month changes and only provide items for visible months
Example of this solution?
hi, plz check the example agenda https://github.com/wix/react-native-calendars/tree/master/example
try this
onDayPress = (date) => {
this.setState({
date: new Date(date.year, date.month-1, date.day),
});
};
onDayChange = (date) => {
this.setState({
date: new Date(date.year, date.month-1, date.day),
});
};
render() {
const items = {
[format(new Date(this.state.date), 'YYYY-MM-DD')]: [],
...otherItems,
};
return (
<Agenda
items={items}
onDayPress={this.onDayPress}
onDayChange={this.onDayChange}
/>
)
}
Hi, I also got caught on this.
We don't all have very long agendas to display, sometimes having a single initial list and no async loading is fine and having default = empty element would be better for me than spinner
As a sort of middle ground if the minDate and maxDate properties that you can use on Calendar were available to Agenda then you would only need to provide 'empty' details for the dates between min and max that did not have sessions/meetings/etc. minDate and MaxDate would prevent the selection of dates before minDate and after MaxDate.......
Has any progress been made on this?
Not the most elegant, but you could call this function below onDayPress and/or before rendering.
Edit: Wrapped it in a promise.
setEmptyKey(dayString) {
if (!this.state.items.hasOwnProperty(dayString)) {
this.state.items[dayString] = [];
// The purpose of this is to remove empty array without affecting the ui
new Promise((resolve, reject) => {
setTimeout(() => {
delete this.state.items[dayString];
resolve();
}, 1000);
}).catch(error => {
// log if needed.
console.log(error);
});
}
}
@bernzJ The problem with this approach (deleting this.state.items[dayString] after 1 sec) is that when the user taps an empty date (say, Sept 5), then taps an empty date after that (Sept 6), the agenda scrolls upwards instead of downwards, which looks strange since you're advancing forward in time.
I've essentially done the same thing, but removed the deletion.
setEmptyKey(dayString) {
if (!this.state.items[dayString]) {
this.state.items[dayString] = [];
}
}
node_modules/react-native-calendars/src/agenda/reservation-list/index.js
in this file,
find activityindicator in render method and change this code. for example:
if (!this.props.reservations || !this.props.reservations[this.props.selectedDay.toString('yyyy-MM-dd')]) {
return (
}
@oliviachang29 after observing some odd issues and reading a bit more about react-native component , I came up with this solution :
setEmptyKey(dayString) {
if (!this.state.items[dayString]) {
let clone = Object.assign({}, this.state.items, { [dayString]: [] });
this.setState({ items: clone });
//this.state.items[dayString] = [];
}
}
I found out that editing directly state object can cause some very unexpected behaviors. The gist of it is explained here: https://facebook.github.io/react/docs/react-component.html#setstate
@tautvilas I've seen your example in the repo, however am I right in saying you should never be setting your state using this.state.items = [] ? it should always be this.setState?
@binhluong2012 I am also facing the issue....any update on it?
I am also facing same issue. I get only selected dates in fetch response.I am getting spin loading on that date which is not persent in response.Can any body suggest me.
This is my code:
constructor(props) {
super(props);
this.state = {
date: new Date(),
items:{},
selectedMonth:''
};
}
componentWillMount() {
const currentDate = Moment(this.state.date, 'YYYY/MM/DD');
const month = currentDate.format('M');
const year = currentDate.format('YYYY');
this.getMonthYear(month,year);
}
render(){
return(
items={this.state.items}
loadItemsForMonth={this.loadItemsForMonth(this.state.date)}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={() => {return (
rowHasChanged={this.rowHasChanged.bind(this)}
onDayPress={(date) => { this.getMonthYear(date.month,date.year); }}
/>
);
}
loadItemsForMonth(h){
fetch('*******', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
Email: "**",
Password: "**",
DeviceType:"Android"
}
)
})
.then((response) => response.json())
.then((res) => {
const activity = res.data.activity;
for (let i = 0; i < activity.length; i++) {
const strTime = this.timeToString(activity[i].ActivityStartDate);
if (!this.state.items[strTime]){
this.state.items[strTime] = [];
}
this.state.items[strTime].push({
name: activity[i].Subject
});
}
})
.done();
}
renderItem(item) {
return (
);
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
renderEmptyDate() {
return (
);
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
getMonthYear(M,Y) {
const month = M - 1;
const monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December',
];
this.setState({selectedMonth: monthNames[month]+' '+Y, showMonth: true });
}
}
I am also facing a similar issue. My observation is, whatever date I've set in selected field of Agenda, this component calls loadItemsForMonth method twice. In second iteration, it takes previous month than the selected date.
E.g. my selected date is 20 April 2018. In first iteration, it fetches the data for this date. in second iteration it takes 20 March 2018. Now as I don't have a data for this date, I see forever loading.
having the same problem. loading twice, current and previous month. i already provided empty arrays for empty dates.
The documentation is wrong, the prop should be renderEmptyData and NOT renderEmptyDate
This is really so strange. I found so many issues regarding show spinner when no date is available for the provided date, but the owners are not doing anything to solve this problem. They just say it is a feature, just return empty array for that days... But what if we don't want show empty rows there?? Anyway now I will fork this package and will try to solve the problem. But really I am disappointed with this kind of management approach...
@gopidon This is the correct answer here, just switched to renderEmptyData and fixed my issue
This is really so strange. I found so many issues regarding show spinner when no date is available for the provided date, but the owners are not doing anything to solve this problem. They just say it is a feature, just return empty array for that days... But what if we don't want show empty rows there?? Anyway now I will fork this package and will try to solve the problem. But really I am disappointed with this kind of management approach...
@DavitVosk
Were you ever able to make a package?
Thanks so much @sibelius, works very well for me your solutions!
thanks, @gopidon, problem solved!
this props = renderEmptyData={() => { return null }}
resolved for me!

this props = renderEmptyData={() => { return null }}
resolved for me!
Or simply:
renderEmptyData={() => null}
Most helpful comment
The documentation is wrong, the prop should be renderEmptyData and NOT renderEmptyDate