-1

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 ?

Antonin Mrchd
  • 656
  • 3
  • 9
  • 31

1 Answers1

0

FOR PEOPLE WHO NEED AN ANSWER

I find how to resolve this problem, I just have to do this command line :

bin/rake db:mongoid:create_indexes

And it work well.

Antonin Mrchd
  • 656
  • 3
  • 9
  • 31