I work on an application that already exist, and I have to create a new feature that is already exist, I just have to copy past the code and change some words.
This code is simple, when you arrive on the page there is a map on the right and some exam_centers on the left, with json data shown with mustache. It already exist with school on the app, so I copy / paste all the code.
When I arrive on the page I have the good datas. But when I drag and drop on the map and click refresh button I have this error in my network console :
Showing <path>/index.json.rabl where line #2 raised:
error processing query: ns=db-<site>.exam_centers limit=30Tree: GEONEAR field=coordinates maxdist=0.00118958 isNearSphere=1
Sort: {}
Proj: {}
planner returned error: unable to find index for $geoNear query (2)
And on this system that already exist on the app, we don't have this error.
Here is the code :
javascript/application/api.js
// Exam centers API - get by city & department || get by latitude longitude
function api_get_exam_centers_by_coordinates(latitude, longitude, onSuccess, radius) {
var url = '/api/exam_centers?latitude='+latitude+'&longitude='+longitude;
if (radius) url += '&radius='+radius;
console.log(latitude);
console.log(longitude);
console.log(onSuccess);
console.log(radius);
$.getJSON(url, onSuccess);
}
// this one work well
function api_get_exam_centers_by_department_and_city(department, city, onSuccess) {
var url = '/api/exam_centers?department='+department;
if (city)
url += ('&city='+city);
$.getJSON(url, onSuccess);
javascript/application/exam_centers.js.erb
$(document).ready(function(){
var map_exam;
var map_current_center;
var fit_map_to_bounds = true;
var featureLayer;
var geojsonLayer;
var search_latitude;
var search_longitude;
var centerMarker;
var cpt =false;
var map_e = $('#map-exams');
if (map_e.length > 0) {
search_latitude = map_e.data('latitude');
search_longitude = map_e.data('longitude');
if (map_e.data('latitude'))
displayExamCentersByCoordinates(map_e.data('latitude'), map_e.data('longitude'), true);
else if (map_e.data('department'))
handleDepartmentChosen(map_e.data('department'), map_e.data('city'));
}
function getProperIcon(feature) {
var icon = '<%= image_url('Pin_Unknown.png') %>';
if (feature.properties.is_la_poste) {
icon = '<%= image_url('Pin_LaPoste.png') %>';
}
if (feature.properties.is_sgs) {
icon = '<%= image_url('Pin_Sgs.png') %>';
}
if (feature.properties.is_codengo) {
icon = '<%= image_url('Pin_Codengo.png') %>' ;
}
return L.icon({
iconUrl: icon,
popupAnchor: [15, -2]
});
}
function onEachFeature(feature, layer) {
if (feature.properties) {
layer.on('click', function () {
var contactTopPosition = 0;
if ($('#listResultsExams').find("[data-marker='" + feature.properties.title + "']").position()) {
contactTopPosition = $("ul#listResultsExams").scrollTop() + $('#listResultsExams').find("[data-marker='" + feature.properties.title + "']").position().top;
}
$("#listResultsExams").animate({ scrollTop:contactTopPosition }, 300);
});
var popup_content = Handlebars.compile($('#ExamCenterPopupTpl').html())(feature.properties);
var popup = L.popup({ autoPan: false }).setContent(popup_content);
layer.bindPopup(popup);
var icon = getProperIcon(feature);
layer.setIcon(icon);
}
}
function displayExamCentersByCoordinates(latitude, longitude, isFirstLoad, radius) {
$('.map-loader-exam').removeClass('hide');
fit_map_to_bounds = (typeof radius == 'undefined');
api_get_exam_centers_by_coordinates(latitude, longitude, isFirstLoad ? handleExamCentersReceivedAtFirstLoad : handleExamCentersReceived, radius);
}
function fill_right_panel(response) {
$('.exams-loader').addClass('hide');
$('#listResultsExams').html(Handlebars.compile($('#ExamCenterListTpl').html())(response));
var url = window.location.href;
$('.entry-line-small').each(function () {
var rating_box = $(this).find('.rating');
rating_box.raty({ readOnly: true, score: rating_box.data('score')});
});
}
function sort_exam_centers_in_right_panel() {
$('#sorting_by_default').click(function () {
$('#listResultsExams>.entry-line-small').tsort({attr: 'data-is-center', order: 'desc'}, {attr: 'data-distance-from-center', order: 'asc'});
});
$('#sorting_by_la_poste').click(function () {
$('#listResultsExams>.entry-line-small').tsort({attr: 'data-is-la-poste', order: 'desc'}, {attr: 'data-distance-from-center', order: 'asc'});
});
$('#sorting_by_sgs').click(function () {
$('#listResultsExams>.entry-line-small').tsort({attr: 'data-is-sgs', order: 'desc'}, {attr: 'data-distance-from-center', order: 'asc'});
});
$('#sorting_by_codengo').click(function () {
$('#listResultsExams>.entry-line-small').tsort({attr: 'data-is-codengo', order: 'desc'}, {attr: 'data-distance-from-center', order: 'asc'});
});
$('#sorting_by_default').trigger('click');
}
function init_map() {
L.LatLng.MAX_MARGIN = 1e-3; // Little hack to avoid reloading schools when zooming with +/-
if (!map_exam) {
map_exam = L.mapbox.map('map-exams', 'edschlum.n3l5in38');
featureLayer = L.mapbox.featureLayer();
$('#map-refresh-btn-exam').click(function (e) {
e.preventDefault();
$('.map-auto-refresh-exam').removeClass('hide');
$(this).addClass('hide');
var center = map_exam.getCenter();
search_latitude = center.lat;
search_longitude = center.lng;
console.log(handleExamCentersReceived());
// result -> exam_center.js?body=1:175 Uncaught TypeError: Cannot read property 'features' of undefined
displayExamCentersByCoordinates(search_latitude, search_longitude, handleExamCentersReceived, getMapRadius());
mixpanel.track('Click refresh btn on map');
});
map_exam.on('mouseup', function (e) {
var new_center = map_exam.getCenter();
if (!new_center.equals(map_current_center)) {
search_latitude = new_center.lat;
search_longitude = new_center.lng;
if ($('.map-auto-refresh-checkbox').prop('checked')) {
displayExamCentersByCoordinates(search_latitude, search_longitude, handleExamCentersReceived, getMapRadius());
}
else {
map_current_center = new_center;
$('.map-auto-refresh-exam').addClass('hide');
$('#map-refresh-btn-exam').removeClass('hide');
}
}
});
map_exam.on('mousemove', function(e) {
var new_center = map_exam.getCenter();
if (centerMarker)
centerMarker.setLatLng(L.latLng(new_center.lat, new_center.lng));
});
}
}
function add_exam_centers_to_map(response) {
featureLayer.clearLayers();
geojsonLayer = L.geoJson(response, {
onEachFeature: onEachFeature
});
featureLayer.addLayer(geojsonLayer).addTo(map_exam);
if (fit_map_to_bounds) map_exam.fitBounds(featureLayer.getBounds());
map_current_center = map_exam.getCenter();
$('.entry-line-small').hover(function (e) {
var name_id = this.getAttribute('data-marker');
getMarker(name_id).openPopup();
});
}
function getMarker(title) {
var layers = geojsonLayer._layers;
var marker;
for (m_index in layers) {
marker = layers[m_index];
if (title && marker.feature.properties.title === title)
return marker;
}
}
function handleExamCentersReceivedAtFirstLoad(response) {
console.log(response);
add_exam_centers_methods(response.features);
fill_right_panel(response);
sort_exam_centers_in_right_panel();
if ($('#map-exams').length > 0 && $('#map-exams').is(':visible')) {
$('.map-loader-exam').addClass('hide');
$('.map-auto-refresh-exam').removeClass('hide');
if ($("#city-list").length == 0) {
init_map();
displayCenterMarker();
add_exam_centers_to_map(response);
}
}
$('.map_over').popover();
}
function handleExamCentersReceived(response) {
add_exam_centers_methods(response.features);
fill_right_panel(response);
sort_exam_centers_in_right_panel();
if ($('#map-exams').length > 0 && $('#map-exams').is(':visible')) {
init_map();
displayCenterMarker();
add_exam_centers_to_map(response);
}
}
function handleDepartmentChosen(department, city) {
$('.map-loader-exam').removeClass('hide');
api_get_exam_centers_by_department_and_city(department, city, handleExamCentersReceivedAtFirstLoad);
}
function displayCenterMarker() {
if (search_latitude && search_longitude) {
if (centerMarker)
centerMarker.setLatLng(L.latLng(search_latitude, search_longitude));
else {
var currentLocationMarker = L.icon({
iconUrl: '<%= image_url('Pin_Center.png') %>',
iconAnchor: [-20, 5]
});
centerMarker = L.marker([search_latitude, search_longitude], {icon: currentLocationMarker});
centerMarker.addTo(map_exam);
}
}
}
function getMapRadius() {
var radius = 0;
if (map_exam)
radius = map_exam.getBounds().getNorthWest().distanceTo(map_exam.getBounds().getSouthEast())/2;
return radius;
}
function add_exam_centers_methods(exam_center_features) {
$.each(exam_center_features, function(key, feature) {
if (feature.properties.distance_from_center) {
if (feature.properties.distance_from_center >= 1) {
feature.properties['distance_formatted'] = Math.round(feature.properties.distance_from_center * 10) / 10;
feature.properties['distance_unit'] = 'km'
} else {
feature.properties['distance_formatted'] = Math.round(feature.properties.distance_from_center * 1000);
feature.properties['distance_unit'] = 'm'
}
}
});
}
});
controllers/api/exam_centers_controller.rb
class Api::ExamCentersController < ApplicationController
caches_action :index, :cache_path => Proc.new {|c| c.request.url }, :expires_in => 1.day, :unless => proc { params[:latitude].present? }
def index
if params[:latitude].present? && params[:longitude].present?
radius = if params[:radius].blank?
20
else
params[:radius].to_f / 1000
end
@center = [params[:latitude], params[:longitude]]
@exam_centers = ExamCenter.near([params[:latitude], params[:longitude]], radius, units: :km).limit(30)
elsif params[:department].present?
@department = Department.where(department_namespace: params[:department]).first
if params[:city].blank?
exam_centers_criteria = ExamCenter.where(zipcode: /^#{@department.zipcode_first_two_digits}/ )
else
exam_centers_criteria= ExamCenter.where(zipcode: /^#{@department.zipcode_first_two_digits}/ )
end
@exam_centers = exam_centers_criteria.asc(:title)
end
end
def show
@exam_center = ExamCenter.find params[:id]
end
end
views/api/base.geojson.rabl
node :type do
'Feature'
end
node :geometry do |examcenter|
{
type: 'Point',
coordinates: examcenter.coordinates
}
end
node :properties do |examcenter|
data = {}
[:id, :title, :adress, :zipcode, :city, :type, :link, :ratings_count, :avg_ratings_score].map do |field|
data[field] = examcenter.send field
end
data[:is_la_poste] = examcenter.isLaPoste?
data[:is_sgs] = examcenter.isSGS?
data[:is_codengo] = examcenter.isCodengo?
data[:http_path] = specific_exam_center_path(examcenter.department.department_namespace, city: examcenter.city_namespace, title: examcenter.title_namespace)
unless @center.blank?
data[:distance_from_center] = examcenter.distance_from(@center).round(2)
end
data.keep_if {|key, value| value.present?}
end
views/api/index.geojson.rabl
object false
node :type do
'FeatureCollection'
end
child @exam_centers => :features do
extends 'api/exam_centers/base'
end
#collection @exam_centers
#extends 'api/exam_centers/show'
views/api/show.geojson.rabl
object @exam_center
attributes :id, :coordinates, :title, :adress, :zipcode, :city, :type, :link, :city_namespace, :title_namespace, :ratings_count, :avg_ratings_score
note
right now, when I try to console.log(handleExamCentersReceived());
I have this error :
exam_center.js?body=1:175 Uncaught TypeError: Cannot read property 'features' of undefined
And I don't understand why,
someone could help me ?