Fetching User Data

In notebook:
Building Modern Web Apps
Created at:
2016-01-24
Updated:
2016-06-12
Tags:
React libraries JavaScript Ampersand
So now we're at a point where we have full access to the Github API.

Github documentation is very good.
just use ​GET /user​ (from Github api docs)

Use this inside the me model. The ampersand model already has a ​fetch()​ method so we can immediately start using it. 
  // **** models/me.js ****
import ...

export default Model.extend({
    // ++++ 1. define the url
    url: 'https://api.github/user',
    
    initialize () {
        this.token = window.localStorage.token;
        this.on('change:token', this.onTokenChange)
    },
    
    props: {...},
    
    session: {
        token: 'string'
    },
    onTokenChange () {
        window.localStorage.token = this.token
    }
    
})
Now we can just ​app.me.fetch()​ and it will try to fetch the data from the ​url​ we provided in the model. No argument is necessary for the ​fetch()​.
It tries fetch the son from the url​ property we added.

But we need to add the token. Or the best is to use an authorisation header, with ajaxConfig:
  // **** models/me.js ****
import ...

export default Model.extend({
    // ++++ 1. define the url
    url: 'https://api.github/user',
    initialize () { ... },
    
    props: {
        id: 'number',
        login: 'string',
        avatar_url: 'string'
    },
    
    session: {...},
    onTokenChange () {...},
    
    // ++++ 2. Send the authorisation headers
    ajaxConfig () {
        return {
            headers: {
                Authorization: 'token' + this.token
            }
        }
    }
})
So now we are directly talking to the Github servers. In the ​user​ (see the ​url​ definition above) we get back a big object with lots of useful info about the logged in user.

It automatically sets properties on model we specified

All the properties we specified in ​props​ and ​session​ are automatically filled from the response. E.g. ​app.me.login​ or ​app.me.avatar_url​ (see above for ​props​)
Compared to Backbone, it will only store the info that we specified, not all of them.
We always want to fetch the ​user​ object (if they log in, or if they have one in localStorage)
We need to add a ​fetchInitialdData​ method for that.
  // **** models/me.js ****
import ...

export default Model.extend({
    // ++++ 1. define the url
    url: 'https://api.github/user',
    initialize () { ... },
    
    props: {...},
    
    session: {...},
    onTokenChange () {
        window.localStorage.token = this.token
        // ++++ 2. Every time the token changes
        // fetch the initial data
        this.fetchInitialData()
    },
    
    ajaxConfig () {...}
    
    // ++++ 1. Add fetchInitialData method
    fetchInitialData () {
        if(this.token){
            this.fetch()
        }
    }
})

More about Ampersand model

​fetch​ method
​on('change:token'...)​ handler
Any property you set (​props​, ​session​) are observable 
Also calls in app.js the fetchInitialData (to make sure data is fetched on bootup)
Doesn't do it in the model initialisation because later it can create timing issues and to keep the model more generic.
  // **** app.js ****
import ...


window.app = app

app.extend({
    init () {
        this.me = new Me()
        // ++++ 1. fetch initial data
        this.me.fetchInitialData()
        this.router = new Router();
        this.router.history.start();
    }
})

app.init();
Both cases are handled:
  1. we already have a token
  2. during the app lifecycle are token is set (​.on('change:token'...)​)
Tip: in Chrome devtools right-click and choose "LogXMLHttpRequests" to see all ajax xhr, xmlhttprequests made