#Introduction

In this lab you'll fetch Yelp data based on the latitude and longitude corresponding
to the city.

#Steps

??Define the store

Edit the main view model. 

Import `data/Store.mjs`.

    import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';

Add a config _businesses_ in the `stores` config block

    stores: {
        businesses: {
            module: Store,
            url:"https://nameless-tundra-27404.herokuapp.com/go/?fn=yelp&latitude=43.084&longitude=-89.546&term=pizza&limit=1",
            responseRoot: 'businesses',
            autoLoad: true
        }
    }

Save and refresh then look in the debugger's Network tab. You should see the data being fetched.

<img style="border: thin solid gray" src="https://s3.amazonaws.com/mjs.neo.learning.images/yelp/initialNetworkTraffic.png"></img>

??Load the store procedurally

Remove the `autoLoad:true,`.

Edit the main view controller and add a statement to load the store.

<pre style='color:lightgray; padding: 8px;'>
doFetchYelpData() {
    const model = this.getModel();
    <span style="color:firebrick">model.stores.businesses.load();</span>
}
</pre>

If you were to save and refresh, and look in network traffic, you'd see
the url being run twice: once when the _center_ changed and once when
the _category_ changed. (In theory we could buffer the method that calls
the Yelp service, but for the lab we're not going to bother.)

??Update search parameters dynamically

Edit the main view model and replace the `url` with this value.

    url:"https://nameless-tundra-27404.herokuapp.com/go/",

That URL omits the query fields &mdash; we'll be adding those dynamically.

Edit the main view controller and update the `load()` params to include 
the _method_, _latitude_, and _longitude_, and _category.

<pre style='color:lightgray; padding: 8px;'>
doFetchYelpData() {
    const model = this.getModel();
    <span style="color:firebrick">const params = {
        fn: 'yelp',
        latitude: model.data.center.lat,
        longitude: model.data.center.lng,
        term: model.data.category
    };
    model.stores.businesses.load({ method: 'GET', params });</span>
}
</pre>

Test this by saving, refreshing, then changing the city a few times. 
With each city changes you should see a new call to the Yelp web service.

<img style="border:thin solid gray" src="https://s3.amazonaws.com/mjs.neo.learning.images/yelp/CityChangesReflectedInTheFeed.png"></img>

??Add two fields to the store's model config

As you probably recall, the Google Maps component expects a store whose records specify
a _title_, and a _position_. The Yelp feed has values that looks like this:

    ...
    "name": "Joe's Diner",
    "coordinates": {
        "latitude": 43.0753733442932,
        "longitude": -89.5296266588608
    },
    ...

Therefore, we need to add a two fields in the store's `fields:[]`.

    model: {
        fields: [{
            name: 'title',
            mapping: 'name'
        }, {
            name: 'position',
            calculate: (data, field, item) => ({ lat: item.coordinates.latitude, lng: item.coordinates.longitude })
        }]
    },

Save, refresh, then use the debugger console to verity that the records reflect those values.

This should show the title of the first record.

    Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].title;

This should show the position (lat, lng) of the first record.

    Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].position


??Don't peek...

You can peek. If you get stuck, or just to compare to another implementation, here's the 
full store and controller logic in invisible writing. Highlight the code to read it.

Your code may differ slightly to reflect your preferences for default city, etc., 
but this code will show how the store is configured and how the controller dynamically 
fetches the data.

Here's the view model.

<pre style="border:thin solid #dddddd; padding: 4px; color: white">

import Base from '../../../node_modules/neo.mjs/src/model/Component.mjs';
import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';

class MainViewModel extends Base {
    static config = {
        className: 'Y.view.MainViewModel',

        data: {
            city: 'Oconomowoc, Wisconsin',
            category: 'pizza',
            center: {
                lat: -27.1259626,
                lng: -109.4088545
            },
        },
        stores: {
            businesses: {
                module: Store,
                url: "https://nameless-tundra-27404.herokuapp.com/go/",
                responseRoot: 'businesses',
                model: {
                    fields: [{
                        name: 'title',
                        mapping: 'name'
                    }, {
                        name: 'position',
                        calculate: (data, field, item) => ({lat: item.coordinates.latitude, lng: item.coordinates.longitude})
                    }]
                }
            }
        }

    }
}

Neo.setupClass(MainViewModel);

export default MainViewModel;
</pre>

Here's the main view controller.

<pre style="border:thin solid #dddddd; padding: 4px; color: white">
import Base from '../../../node_modules/neo.mjs/src/controller/Component.mjs';

class MainViewController extends Base {
    static config = {
        className: 'Y.view.MainViewController',
    }

    onComponentConstructed() {
        const model = this.getModel();
        this.onCityChange(model.data.city);
        model.on('dataPropertyChange', data => {
            if (data.key === 'city') this.onCityChange(data.value);
            if (data.key === 'center') this.doFetchYData();
            if (data.key === 'category') this.doFetchYData();
        });
    }
    onCityChange(city) {
        if (!city) return;
        Neo.main.addon.GoogleMaps.geocode({address: city})
            .then(data => this.getModel().data.center = data.results[0].geometry.location);
    }

    doFetchYData() {
        const model = this.getModel();
        console.log('Fetch Yelp data', model.data.center, model.data.category);
        const params = {
            fn: 'yelp',
            latitude: model.data.center.lat,
            longitude: model.data.center.lng,
            term: model.data.category,
            limit: 20,
        };
        model.stores.businesses.load({method: 'GET', params});
    }


}

Neo.setupClass(MainViewController);

export default MainViewController;
</pre>

??Bind the store to the map

You have the map center, and a store that holds the information the map expects.

Edit `view/businesses/Tabs.mjs` and add an additional binding to the map:

<pre style='color:lightgray'>
bind: {
    center: data => data.center,
    <span style="color:firebrick">markerStore: 'stores.businesses'</span>
},
</pre>

Save, refresh, then change the category a few times &mdash; the markers should
update at the specification city. Change city and see the markers for that 
location and category.

