Repo Detail Page

In notebook:
Building Modern Web Apps
Created at:
2016-01-28
Updated:
2016-01-28
Tags:
libraries JavaScript React Ampersand
Creates pages/repo-detail.js

Creates a react component and copy-pase html code
  // ****     pages/repo-detail.js    ****
// ++++ 0. create file pages/repo-detail.js

import React from 'react'

export default React.createClass({
    displayName: 'RepoDetail'
    
    render () {
        const {repo} = this.props
        
        return (
            <div className='container'>
                <h1>{repo.full_name}</h1>
                <p></p>
                <ul></ul>
            </div>
        )    
    }
})
The case when the user arrives directly a repo page. In this case we haven't fetched any data.
We have to make sure it always gets a model.

First we need to add this page to the router:
  // ****     router.js       ****
import ...

export default Router.extend({
    renderPage (page, opts = {layout:true}) { ... }
    
    routes: { 
        '': 'public',
        'repos': 'repos',
        'login': 'login',
        'logout': 'logout',
        'auth/callback?:query': 'authCallback',
        // ++++ 1. Add the repo route
        // adds a namespace
        'repo/:owner/:name': 'repoDetail'
        // a full_name of a github repo already contains the '/'
        
    },
    public () { ... },
    repos () { ... },
    
    // ++++ 2. Create the route handler
    repoDetail (owner, name) {
        // we need to extract the corresponding repo from the collection
    }
    
    login () { ... },

    authCallback (query) { ... },

    logout () { ... }   
})
For the ​repoDetail​ handler we need to find the corresponding repo from the collection.
Ampersand model has a find method, but he will add it directly on the model:
  // ****     repo-collection.js      ****
import Collection from 'ampersand-rest-collection'
import Repo from './repo'
import githubMixin from '../helpers/github-mixin'

export default Collection.extend({
    url: 'https://api.github.com/user/repos', 
    model: Repo, 
    
    // ++++ 1. Add the find method to the collection:
    getByFullName (fullName) {
        let model = this.findWhere({full_name: fullName})
        
        if(!model){
            // we need to CREATE a new model
            model = new Repo({full_name: fullName})
            // this solution will work if we start on the repos page
            // this create a new model, will a full_name property
        }
        return model
    }
})
We can continue with ​repoDetail​ handler in router
  // ****     router.js       ****
import ...
// ++++ 2. of course we need to import the layout
import RepoDetail from './pages/repo-detail'

export default Router.extend({
    renderPage (page, opts = {layout:true}) { ... }
    
    routes: { 
        '': 'public',
        'repos': 'repos',
        'login': 'login',
        'logout': 'logout',
        'auth/callback?:query': 'authCallback',
        'repo/:owner/:name': 'repoDetail'

    },
    public () { ... },
    repos () { ... },

    repoDetail (owner, name) {
        // we need to extract the corresponding repo from the collection
        // ++++ 1. get the repo
        const model = app.me.repos.getByFullName(owner + '/' + name)
        this.renderPage(<repoDetail repo={model}/>)
    }
    
    login () { ... },

    authCallback (query) { ... },

    logout () { ... }   
})
Finally we need to update app url for the repo detail page
  // ****     repo.js    ****
import Model from 'ampersand-model'

export default Model.extend({
    props: {
        id: 'number',
        name: 'string',
        full_name: 'string'
    }

    derived: {
        appUrl: {
            deps: ['full_name'],
            fn () {
                // ---- 1. instead of this:
                // return '/' + this.full_name
                // ++++ 2. use '/repo/' route
                return '/repo/' + this.full_name
            }
        }
    }
    
})