Skip to content
This repository has been archived by the owner on Jun 27, 2022. It is now read-only.

Commit

Permalink
Changes for History
Browse files Browse the repository at this point in the history
  • Loading branch information
tylermcginnis committed Aug 30, 2017
1 parent 93add38 commit f2f0342
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
3 changes: 2 additions & 1 deletion App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import AddEntry from './components/AddEntry'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers'
import History from './components/History'

export default class App extends React.Component {
render() {
return (
<Provider store={createStore(reducer)}>
<View style={{flex: 1}}>
<AddEntry />
<History />
</View>
</Provider>
)
Expand Down
40 changes: 40 additions & 0 deletions components/History.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { connect } from 'react-redux'
import { receiveEntries, addEntry } from '../actions'
import { timeToString, getDailyReminderValue } from '../utils/helpers'
import { fetchCalendarResults } from '../utils/api'

class History extends Component {
componentDidMount () {
const { dispatch } = this.props

fetchCalendarResults()
.then((entries) => dispatch(receiveEntries(entries)))

This comment has been minimized.

Copy link
@sherry2610

sherry2610 Apr 24, 2020

On line number 13 the return value of fetchCalenderResults promise is null but in the video there was so much data that was returning from this. So why I am getting null?

This comment has been minimized.

Copy link
@xi1570-krupeshanadkat

xi1570-krupeshanadkat Oct 18, 2020

This will solve the problem

_calendar.js (just modified it to results !== null)

export function formatCalendarResults (results) {
  return results !== null
    ? setDummyData()
    : setMissingDates(JSON.parse(results))
}
.then(({ entries }) => {
if (!entries[timeToString()]) {
dispatch(addEntry({
[timeToString()]: getDailyReminderValue()
}))
}
})
.then(() => this.setState(() => ({ready: true})))

This comment has been minimized.

Copy link
@iainmck29

iainmck29 Feb 22, 2021

Can someone explain what this line is doing? The component doesn't use any localised state so why are we using setState here?

This comment has been minimized.

Copy link
@gugol2

gugol2 Feb 22, 2021

I think it is a typo, that part will come in a further step.

The idea is to show something in the meantime the response of the request of the entries is ready, like some sort of spinner or loading bar.

This is what you are missing (in a more modern hooks approach):

const [ready, setReady] = useState(false);

...

if (!ready) {
  return <div>Whatever you prefer that hints that something is loading...</div>;
}

return <View>
      <Text>{JSON.stringify(this.props)}</Text>
    </View>
  
}
render() {
return (
<View>
<Text>{JSON.stringify(this.props)}</Text>
</View>
)
}
}

function mapStateToProps (entries) {
return {
entries
}
}

export default connect(
mapStateToProps,
)(History)
7 changes: 6 additions & 1 deletion utils/api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { AsyncStorage } from 'react-native'
import { CALENDAR_STORAGE_KEY } from './_calendar'
import { formatCalendarResults, CALENDAR_STORAGE_KEY } from './_calendar'

export function fetchCalendarResults () {
return AsyncStorage.getItem(CALENDAR_STORAGE_KEY)
.then(formatCalendarResults)
}

export function submitEntry ({ entry, key }) {
return AsyncStorage.mergeItem(CALENDAR_STORAGE_KEY, JSON.stringify({
Expand Down

12 comments on commit f2f0342

@andrewShillito
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the end of the video the dummy calendar data is visible in the rendered JSON but I had to change the formatCalendarResults function in ./utils/_calendar because at initialization results was !== null ("{}" !== null) thus preventing dummy data loading.

@josemvcerqueira
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to run AsyncStorage.clear() if you submitted any prior data to the "DB". That is why results was not === null.

I ran it inside fetchCalendarResults() one time.

@sanjib
Copy link

@sanjib sanjib commented on f2f0342 May 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the tips, that not only worked but saved valuable debugging time!

@jerryfishzz
Copy link

@jerryfishzz jerryfishzz commented on f2f0342 Jun 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the 14 line of History.js, the second then:

     .then(({ entries }) => {
        if (!entries[timeToString()]) {
          dispatch(addEntry({
            [timeToString()]: getDailyReminderValue()
          }))
        }
      })

({ entries }) will cause a warning in my environment:

[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_ref.entries')]

Stack trace:
components\History.js:18:15 in
node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
node_modules\promise\setimmediate\core.js:123:25 in
...

If I write it in this way, the warning is gone:

     .then(() => {
        const { entries } = this.props
        if (!entries[timeToString()]) {
          dispatch(addEntry({
            [timeToString()]: getDailyReminderValue()
          }))
        }
      })

I am not very familiar with Promise. So I don't know it's my problem or something else. It looks like the argument for then should come from Promise, but not from state or props. ({ entries }) is a destructure from props. So it leads to a warning.

@sanjib
Copy link

@sanjib sanjib commented on f2f0342 Jun 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jerryfishzz, can you double-check it's not (entries) but ({ entries })? Forgetting to destructure is often a common cause for errors. There is no reason for entries to come from props so even if you don't get any any warning, does it work?

@jerryfishzz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sanjibahmad. The problem comes from the first then in my code. Not familiar with ES6 and Promise, I write the first then this way:

.then((entries) => {
  dispatch(receiveEntries(entries))
})

No return value from the first then so as to be the warning in second then.

@luismasg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jerryfishzz, can you double-check it's not (entries) but ({ entries })? Forgetting to destructure is often a common cause for errors. There is no reason for entries to come from props so even if you don't get any any warning, does it work?

I'm not sure why we're destructuring in the second .then but not on the first one.
can anyone explain?

@luismasg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sanjibahmad. The problem comes from the first then in my code. Not familiar with ES6 and Promise, I write the first then this way:

.then((entries) => {
  dispatch(receiveEntries(entries))
})

No return value from the first then so as to be the warning in second then.

Hey!!!!! i found why.
did you return from the previous promise??
turns out dispatch returns a promise with the action you just submitted. thats why yo distructure.
if you dont return . the second .then() getn nothing

  fetchCalendarResults()
      .then(entries => {
        return dispatch(receiveEntries(entries));
      })
      .then(({ entries }) => {
        if (!entries[timeToString()]) {
          dispatch(
            addEntry({
              [timeToString()]: getDailyReminderValue()
            })
          );
        }
      });

notice how the first .then returns.

@gugol2
Copy link

@gugol2 gugol2 commented on f2f0342 May 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sanjibahmad. The problem comes from the first then in my code. Not familiar with ES6 and Promise, I write the first then this way:

.then((entries) => {
  dispatch(receiveEntries(entries))
})

No return value from the first then so as to be the warning in second then.

Hey!!!!! i found why.
did you return from the previous promise??
turns out dispatch returns a promise with the action you just submitted. thats why yo distructure.
if you dont return . the second .then() getn nothing

  fetchCalendarResults()
      .then(entries => {
        return dispatch(receiveEntries(entries));
      })
      .then(({ entries }) => {
        if (!entries[timeToString()]) {
          dispatch(
            addEntry({
              [timeToString()]: getDailyReminderValue()
            })
          );
        }
      });

notice how the first .then returns.

Not quite, dispatch does not return a promise by itself. I mean dispatch (thanks to thunks) only returns plain JS objects which is what arrives to the reducers, thunks will make sure of that.
What it is happening there is that anything that you wrap in a then is therefore 'thenable' (as long as it returns something that something will be thenable). Which means that if that something is really a Promise it will follow the pending and resolved/rejected flow and if it is not it will be returned as a resolved promise with the value of that something.

The other issue, destructuring in the second then... well there you are destructuring the response of dispatch(receiveEntries(entries)) which is:

{
  type: RECEIVE_ENTRIES,
  entries,
}

On the other hand fetchCalendarResults() only returns an object with the entries, not an object with a property entries, so no, you can't do the destructuring in the first then.

@Huazhi-Fang
Copy link

@Huazhi-Fang Huazhi-Fang commented on f2f0342 Aug 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, whether destructuring or not in the second then makes no difference in the output. Not sure why we need destructuring here.

@emrekgn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone get this error: "TypeError: Cannot read property 'getItem' of undefined"

I think this is related to this issue:
facebook/react-native#18372

@abdelkadergelany
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone get this error: "TypeError: Cannot read property 'getItem' of undefined"

I think this is related to this issue:
facebook/react-native#18372

I was getting the same error. But I find out that I was using the old import of AsyncStorage rather than the actual AsyncStorage library
I was mistakenly using this in my utils/api.js
import { AsyncStorage } from 'react-native'
instead of this:
import AsyncStorage from '@react-native-community/async-storage';

Please sign in to comment.