/* 2018 Live Results App - Vue.js app Summary: Displays results in three different places on homepage: Top level results for Sen/Gov/House Key races for Sen/Gov/House Map Slider for Sen/Gov/House Dependencies: Vue js 2.5.13 Axios 0.18.0 Browser Requirements: IE9+ Table of Contents: Shared Variables and Functions Alpha 1 widget Alpha 2 widget Beta 1 widget Technical Notes: Each page is handled as a separate vue app, with it's own component. Except in the case of the homepage, which has three separate apps, one per widget. The homepage has a special process for fetching data due to multiple apps on the same page. It uses a function that accumulates callbacks, but only does one fetch at a time. This reduced the amount of times homepage.json is retrieved. */ // HOMEPAGE DATA FETCH ///////////////////////////////////////////////////////// var rcp_refresh_interval = 30; // Seconds between auto refresh var rcp_hp_fetching_data = false; var rcp_hp_fetch_callbacks = []; var rcp_cache_bust = function() { // Returns a unique value that is different every 10 sec return Math.round(new Date().getTime() / 10000); } var rcp_hp_fetch_data = function(callback) { rcp_hp_fetch_callbacks.push(callback); if(!rcp_hp_fetching_data) { rcp_hp_fetching_data = true; axios.get('/elections/live_results/2018/homepage.json?cache_bust='+rcp_cache_bust()) .then(function(response) { for(var i = 0; i < rcp_hp_fetch_callbacks.length; i++) { rcp_hp_fetch_callbacks[i](response); } rcp_hp_fetch_callbacks = []; rcp_hp_fetching_data = false; }); } } // FUNCTIONS TO HELP SHARE METHODS ACROSS APPS ///////////////////////////////// var rcp_merge_methods = function(obj1,obj2) { var obj3 = {}; for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } return obj3; } var rcp_shared_methods = { capitalize_string : function(str) { return str.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); }); }, races_with_vote_totals : function(races) { // Requires 'races' object be fully populated with data for(var i = 0; i < races.length; i++) { var vote_total = 0; for(var j = 0; j < races[i].reportingUnit.candidates.length; j++) { var c = races[i].reportingUnit.candidates[j]; vote_total += parseInt(c.voteCount); } races[i]['voteTotal'] = vote_total; } return races; }, net_display : function(num) { if(num > 0) { return '(+'+num+')'; } else if(num < 0) { return '('+num+')'; } else { return ''; } }, has_winner : function(race) { var winner = this.find_winner(race); if( typeof winner.party !== 'undefined' ) { return true; } return false; }, winner_party : function(race) { var winner = this.find_winner(race); if( typeof winner.party !== 'undefined' ) { return winner.party.toLowerCase(); } return ''; }, winner_is_pickup : function(race) { var winner = this.find_winner(race); if( typeof winner.party !== 'undefined' ) { if(race.holding_party != this.party_name_to_basename(winner.party)) { return true; } } return false; }, winner_hold_pickup_text : function(race) { var winner = this.find_winner(race); var text = ''; if( typeof winner.party !== 'undefined' ) { var winner_party = winner.party; if(winner['first'] == 'Bernie' && winner['last'] == 'Sanders') { winner_party = 'Dem'; } text += winner_party + ' '; if(race.holding_party != this.party_name_to_basename(winner.party)) { text += 'Pickup'; } else { text += 'Hold'; } } return text; }, vote_perc_display : function(num, total) { if(total > 0) { return (Math.round((parseInt(num) / parseInt(total)) * 1000) / 10).toFixed(1); } else { return "0.0"; } }, party_name_to_basename : function(bn) { if(bn == 'GOP') { return 'gop'; } else if(bn == 'Dem') { return 'dem'; } else { return bn.toLowerCase().replace(/ /g,"_"); } }, party_basename_to_name : function(bn) { if(bn == 'gop') { return 'GOP'; } else if(bn == 'dem') { return 'Dem'; } else { return bn.charAt(0).toUpperCase() + bn.slice(1); // Capitalize } }, find_winner : function(race) { for(var i = 0; i < race.reportingUnit.candidates.length; i++) { var c = race.reportingUnit.candidates[i]; if(c.winner_override != null && c.winner_override.toLowerCase() == 'x') { return c; } } for(var i = 0; i < race.reportingUnit.candidates.length; i++) { var c = race.reportingUnit.candidates[i]; if(c.winner != null && c.winner.toLowerCase() == 'x') { return c; } } return {}; }, candidates_with_party : function(candidates, party, limit) { // NOTE: Right now a limit of anything over 0 does the same thing: // returns highest voted candidate for that party var cwp = this.find_objects(candidates, 'party', party); // Find one matching candidate with most votes var top_index = 0; var top_votes = 0; var return_candidates = []; if(cwp.length > 0 && limit > 0) { for(var i = 0; i < cwp.length; i++) { if(parseInt(cwp[i].voteCount) > top_votes) { top_votes = cwp[i].voteCount; top_index = i; } } return_candidates.push(cwp[top_index]); } return return_candidates; }, column_candidates : function(candidates, col_num) { return this.find_objects(candidates, 'show_in_column', col_num, 1); }, any_column_candidates : function(races, col_num) { for(var i = 0; i < races.length; i++) { var candidates = races[i]['reportingUnit']['candidates']; for(var j = 0; j < candidates.length; j++) { if(candidates[j]['show_in_column'] == col_num) { return true; } } } return false; }, find_objects : function(arr_of_objs, key, val, limit) { var objects = []; var count = 0; if(typeof limit === 'undefined') { limit = 9999999999999999999999; } for(var i = 0; i < arr_of_objs.length; i++) { if( typeof arr_of_objs[i][key] === 'undefined' ) { continue; } if( arr_of_objs[i][key] == val ) { objects.push(arr_of_objs[i]); count++; if(count >= limit) { break; } } } return objects; }, seat_display : function(seat_str) { if(seat_str == 'Unexpired Term') { return 'Special'; } return seat_str; }, party_display : function(c) { if( (c['first'] == 'Bernie' && c['last'] == 'Sanders') || (c['first'] == 'Angus' && c['last'] == 'King') ) { return 'Dem'; } return c['party']; }, race_detail_link : function(race, page_basename) { if(race.seatName == 'Unexpired Term') { return ''; } else { return '/elections/live_results/2018/state/'+race.reportingUnit.statePostal.toLowerCase()+'/'+this.featured_race_type_to_race_type(page_basename)+'/'; } }, featured_race_type_to_race_type : function(str) { var type_matchup = { "senate" : "senate", "governor" : "governor", "house" : "house", "house_top_50" : "house", "house_northeast" : "house", "house_midwest" : "house", "house_south" : "house", "house_west" : "house", }; return type_matchup[str]; }, display_precincts_perc(race) { /*if(race.officeName == 'U.S. Senate' && race.stateName == 'Arizona') { return '(---%)'; }*/ return '('+Math.round(Number(race.reportingUnit.precinctsReportingPct))+'%)'; } }; ///////////////////////////////// // LIVE RESULTS ALPHA 1 WIDGET // ///////////////////////////////// Vue.component('rc-widget-live-results-alpha-1', { template: '\ \
\ \
\
Election 2018
\
\ \
\ \
\ \
\
\
\ \
\
\ \
\
\ \
\ \
\
\
\ \
\
\ \
\
\ \
\ \
\
\
\ \
\
\ \
\
\ \
\ \
****************
\ \
\ \ ', data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "won_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } }, "net_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } } } }, created : function() { this.get_data_for_alpha_1(); // Start refresh cron this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000); }, methods : rcp_merge_methods(rcp_shared_methods, { fetch_data : function() { if(!this.loading) { this.get_data_for_alpha_1(); } }, get_data_for_alpha_1 : function() { this.loading = true; // Retrieve live results data rcp_hp_fetch_data(function(response) { // Successfully retrieved data this.won_seats = response.data.won_seats; this.net_seats = response.data.net_seats; this.first_load_done = true; this.loading = false; }.bind(this)); }, }) }); // END rc-widget-live-results-alpha-1 // Start App if(document.getElementById('live_results_alpha_1')) { new Vue({ el: '#live_results_alpha_1' }); } if(document.getElementById('live_results_alpha_1_mobile')) { new Vue({ el: '#live_results_alpha_1_mobile' }); } ///////////////////////////////// // LIVE RESULTS ALPHA 2 WIDGET // ///////////////////////////////// Vue.component('rc-widget-live-results-alpha-2', { template: '\ \
\ \
\ \
\ \
\ \
\
· ·
\
Refresh
\
\ \
\ Democrats \ Republicans \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
DemocratRepublican
\ \ \ \ \ \
\ \ \ \
\ \
\ \
\ \ ', data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "races" : { "senate" : [], "house" : [], "governor" : [] }, "election_types" : [ { "name" : "Senate", "basename" : "senate", "footer" : "Click Here For All Senate Results" }, { "name" : "Governors", "basename" : "governor", "footer" : "Click Here For All Governor Results" }, { "name" : "House", "basename" : "house", "footer" : "All House Results | Top 50 | Northeast | Midwest | South | West" } ], "won_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } }, "net_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } } } }, created : function() { this.get_data_for_alpha_2(); // Start refresh cron this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000); }, methods : rcp_merge_methods(rcp_shared_methods, { fetch_data : function() { if(!this.loading) { this.get_data_for_alpha_2(); } }, get_data_for_alpha_2 : function() { this.loading = true; // Retrieve live results data rcp_hp_fetch_data(function(response) { // Successfully retrieved data this.won_seats = response.data.won_seats; this.net_seats = response.data.net_seats; // Calculate vote totals for each race based on candidates this.races['senate'] = this.races_with_vote_totals(response.data.homepage_races['senate']); this.races['house'] = this.races_with_vote_totals(response.data.homepage_races['house']); this.races['governor'] = this.races_with_vote_totals(response.data.homepage_races['governor']); this.first_load_done = true; this.loading = false; }.bind(this)); } }) }); // END rc-widget-live-results-alpha-2 // Start App if(document.getElementById('live_results_alpha_2')) { new Vue({ el: '#live_results_alpha_2' }); } if(document.getElementById('live_results_alpha_2_mobile')) { new Vue({ el: '#live_results_alpha_2_mobile' }); } ///////////////////////////////// // LIVE RESULTS ALPHA 3 WIDGET // ///////////////////////////////// Vue.component('rc-widget-live-results-alpha-3', { template: `

Real Clear Politics Election 2018

`, data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "img_map" : { "senate" : "", "house" : "", "governor" : "" }, "election_types" : [ { "name" : "U.S. Senate", "basename" : "senate", "link" : '/elections/live_results/2018/senate/', "footer_txt" : "All Senate Results" }, { "name" : "Governors", "basename" : "governor", "link" : '/elections/live_results/2018/governor/', "footer_txt" : "All Governor Results" }, { "name" : "U.S. House", "basename" : "house", "link" : '/elections/live_results/2018/house/', "footer_txt" : "All House Results" } ], "won_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } }, "net_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } } } }, created : function() { this.get_data_for_alpha_3(); // Start refresh cron this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000); }, methods : rcp_merge_methods(rcp_shared_methods, { fetch_data : function() { if(!this.loading) { this.get_data_for_alpha_3(); } }, get_data_for_alpha_3 : function() { this.loading = true; // Retrieve live results data rcp_hp_fetch_data(function(response) { // Successfully retrieved data this.won_seats = response.data.won_seats; this.net_seats = response.data.net_seats; this.img_map['senate'] = "/elections/live_results/2018/live_map_senate_thumb.png?cache_bust="+rcp_cache_bust(); this.img_map['house'] = "/elections/live_results/2018/live_map_house_thumb.png?cache_bust="+rcp_cache_bust(); this.img_map['governor'] = "/elections/live_results/2018/live_map_governor_thumb.png?cache_bust="+rcp_cache_bust(); this.first_load_done = true; this.loading = false; }.bind(this)); } }) }); // END rc-widget-live-results-alpha-3 // Start App if(document.getElementById('live_results_alpha_3')) { new Vue({ el: '#live_results_alpha_3' }); } //////////////////////////////// // LIVE RESULTS BETA 1 WIDGET // //////////////////////////////// Vue.component('rc-widget-live-results-beta-1', { template: '\ \
\ \
\ \
Election 2018 Results
\ \ \ \
\ \
\ \
\ \
\
\ \ Democrats\
\ \
\ \
Senate Live Results 2018
\ \
\ \
\ \
\ \
\
\ \ Democrats\
\ \
\ \
House Live Results 2018
\ \
\ \
\ \
\ \
\
\ \ Democrats\
\ \
\ \
Governor Live Results 2018
\ \
\ \
\ \
\ \
\ \ ', data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "current_page" : "senate", "img_map" : { "senate" : "", "house" : "", "governor" : "" }, "won_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } }, "net_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } } } }, created : function() { this.get_data_for_beta_1(); // Start refresh cron this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000); }, methods : rcp_merge_methods(rcp_shared_methods, { fetch_data : function() { if(!this.loading) { this.get_data_for_beta_1(); } }, get_data_for_beta_1 : function() { this.loading = true; // Retrieve live results data rcp_hp_fetch_data(function(response) { // Successfully retrieved data this.won_seats = response.data.won_seats; this.net_seats = response.data.net_seats; // Refresh images var types = ['senate','house','governor']; for(var i = 0; i < types.length; i++) { if(this.current_page == types[i]) { // Do smart loading img = new Image(); var vue_this = this; var src = "/elections/live_results/2018/live_map_"+types[i]+"_thumb.png?cache_bust="+rcp_cache_bust(); var callback_apply = function(callback, vue_this, types, i, src) { callback(vue_this, types, i, src); } img.onload = callback_apply(function(vue_this, types, i, src) { vue_this.img_map[types[i]] = src; vue_this.loading = false; }, vue_this, types, i, src); img.src = src; } else { // Just change src... that way images in pages not loaded won't load... reducing http requests this.img_map[types[i]] = "/elections/live_results/2018/live_map_"+types[i]+"_thumb.png?cache_bust="+rcp_cache_bust(); } } this.first_load_done = true; }.bind(this)); } }) }); // END rc-widget-live-results-beta-1 // Start App if(document.getElementById('live_results_beta_1')) { new Vue({ el: '#live_results_beta_1' }); } if(document.getElementById('live_results_beta_1_mobile')) { new Vue({ el: '#live_results_beta_1_mobile' }); } //////////////////////////////// // LIVE RESULTS LANDING PAGES // //////////////////////////////// Vue.component('rc-widget-live-results-body', { props: ['page_basename','page_name','page_sub'], template: '\ \
\ \
\ \
\ \

2018 Election: {{ page_name.substring(1) }}

\

\ \
\ \ \ \
\ \
\ \
2018 {{ result.name }} Results
\ \
\
\
\ \
\
\ \
\ \
\ \
\ \
\ \
\ \
\ All House Results · \ Top 50 · \ Northeast · \ Midwest · \ South · \ West\
\ \
****************
\ \
\ \
\ \
\
· ·
\
Refresh
\
\ \
\ Democrats \ Republicans \
\ \
\
\ \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
DemocratRepublican
\ \
\ \ \ \
\ \
\ \ ', data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "current_page" : "senate", "img_map" : "", "state_links": [], "races" : { "governor" : [], "house" : [], "senate" : [], "house_top_50" : [], "house_northeast" : [], "house_midwest" : [], "house_south" : [], "house_west" : [] }, "dropdown_link" : { "governor" : "0", "house" : "0", "senate" : "0" }, "top_results": [ { "name" : "Senate", "basename" : "senate" }, { "name" : "House", "basename" : "house" }, { "name" : "Governors", "basename" : "governor" } ], "won_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } }, "net_seats": { "senate": { "gop": 0, "dem": 0, "other": 0 }, "governor": { "gop": 0, "dem": 0, "other": 0 }, "house": { "gop": 0, "dem": 0, "other": 0 } } } }, created : function() { this.get_data_for_page(); // Start refresh cron this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000); }, methods : rcp_merge_methods(rcp_shared_methods, { is_main_type : function(type) { for(var i = 0; i < this.top_results.length; i++) { if(this.top_results[i]['basename'] == type) { return true; } } return false; }, fetch_data : function() { if(!this.loading) { this.get_data_for_page(); } }, get_data_for_page : function() { this.loading = true; // Retrieve live results data axios.get('/elections/live_results/2018/'+this.page_basename+'.json?cache_bust='+rcp_cache_bust()) .then(function(response) { // Successfully retrieved data this.won_seats = response.data.won_seats; this.net_seats = response.data.net_seats; this.state_links = response.data.state_links; this.races[this.page_basename] = this.races_with_vote_totals(response.data.races); // Refresh images // Do smart loading img = new Image(); var vue_this = this; var src = "/elections/live_results/2018/live_map_"+this.page_basename+".png?cache_bust="+rcp_cache_bust(); var callback_apply = function(callback, vue_this, src) { callback(vue_this, src); } img.onload = callback_apply(function(vue_this, src) { vue_this.img_map = src; vue_this.loading = false; }, vue_this, src); img.src = src; this.first_load_done = true; }.bind(this)); }, go_to_dropdown_link : function(bn) { if(this.dropdown_link[bn] != "0") { window.location.href = this.dropdown_link[bn]; } } }) }); // END rc-widget-live-results-body // GOVERNOR LANDING PAGE Vue.component('rc-widget-live-results-governor', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_governor')) { new Vue({ el: '#live_results_governor' }); } // HOUSE LANDING PAGE Vue.component('rc-widget-live-results-house', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house')) { new Vue({ el: '#live_results_house' }); } // SENATE LANDING PAGE Vue.component('rc-widget-live-results-senate', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_senate')) { new Vue({ el: '#live_results_senate' }); } // HOUSE TOP 50 LANDING PAGE Vue.component('rc-widget-live-results-house-top-50', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house_top_50')) { new Vue({ el: '#live_results_house_top_50' }); } // HOUSE NORTHEAST LANDING PAGE Vue.component('rc-widget-live-results-house-northeast', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house_northeast')) { new Vue({ el: '#live_results_house_northeast' }); } // HOUSE MIDWEST LANDING PAGE Vue.component('rc-widget-live-results-house-midwest', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house_midwest')) { new Vue({ el: '#live_results_house_midwest' }); } // HOUSE SOUTH LANDING PAGE Vue.component('rc-widget-live-results-house-south', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house_south')) { new Vue({ el: '#live_results_house_south' }); } // HOUSE WEST LANDING PAGE Vue.component('rc-widget-live-results-house-west', { template: '\ \
\ \ \ \
\ \ ' }); // Start App if(document.getElementById('live_results_house_west')) { new Vue({ el: '#live_results_house_west' }); } /////////////////////// // STATE LEVEL PAGES // /////////////////////// Vue.component('reporting-unit', { props: ['data'], template: '\ \
\
\ {{ data[\'county_name\'] ? data[\'county_name\']+county_str(data) : data[\'district_name\'] }} \ Final Results\ {{ data[\'precincts_reporting\'] }}% Reporting\ \
\ \ \ \ \ \ \ \ \
\ checkmark\ \
\
\ \ ', methods : { county_str : function(race) { if(race['region_key'] != 'ME') { return ' County'; } return ''; } } }); Vue.component('rc-widget-live-results-state', { props: ['state_postal','state_type'], template: '\ \
\ \
****************
\ \
\ \
\ \

2018 {{ capitalize_string(map_state_data[\'state_name\']) }} {{ capitalize_string(state_type) }} Election Results

\ \
\ \
\ \
\ \
\ \ \ \
\ \
\
\
\
\
\
x
\
\
\
\
\
\ \ \ \ \ \ \
Dem Gop Other
\
\
\
\ \
\ \ \ \
\ \
\ \ ', data : function() { return { "loading_interval" : 0, "loading" : true, "first_load_done" : false, "map_state_data" : { "type" : map_state_data['type'], "state" : map_state_data['state'], "ingov" : map_state_data['ingov'], "insenate" : map_state_data['insenate'], "state_name" : map_state_data['state_name'] }, "nav_sections" : ['senate','governor','house'], "reporting_units" : [], "top_ru" : [] } }, created : function() { this.get_data_for_state(); // Start refresh cron /*this.loading_interval = setInterval(function() { this.fetch_data(); }.bind(this), rcp_refresh_interval * 1000);*/ }, methods : rcp_merge_methods(rcp_shared_methods, { fetch_data : function() { if(!this.loading) { this.get_data_for_state(); } }, get_data_for_state : function() { this.loading = true; // Retrieve live results data var file_name = 'counties_'+this.state_type; if(this.state_type == 'house') { file_name = 'districts_'+this.state_type; } axios.get('/elections/live_results/2018/'+file_name+'.json?cache_bust='+rcp_cache_bust()) .then(function(response) { // Successfully retrieved data // Set global variable for d3 map, then trigger window.map_county_data = response.data.map_county_data; window.county_map_data_done_loading(); // Grab this state's reporting units for(var i = 0; i < response.data.map_county_data.election.race.length; i++) { var race = response.data.map_county_data.election.race[i]; if(race['region_key'].toLowerCase() == this.state_postal) { this.reporting_units.push(race); } } // Grab top level reporting unit this.top_ru = response.data.top_level_ru; this.first_load_done = true; this.loading = false; }.bind(this)); }, top_race : function(postal) { for(var i = 0; i < this.top_ru.length; i++) { if(this.top_ru[i]['region_key'].toLowerCase() == postal.toLowerCase()) { return this.top_ru[i]; } } return {}; }, }) }); // Start App if(document.getElementById('live_results_state')) { new Vue({ el: '#live_results_state' }); }