RailsMap - Dynamically updating markers using Ajax only upon search result alteration

Recently, I've been developing a small app with the assistance of stackoverflow. The main goal is to plot a list of locations onto a searchable/pannable google map. This type of functionality can be seen all over the web. The locations are stored on the backend and then passed to the view by the controller. AJAX is used to avoid reloading the entire page. Here are the scenarios: a) When a user searches for a location via zipcode, the map loads the new location, sends a search request to the server, displays any markers within a set radius, and sets a default zoom level; b) If the user pans or zooms around, the map stays at the user's chosen position, sends a search request with the viewport bounding box to the server, and maps the results. Initially, the map defaults to Seattle, and it attempts to geolocate the user...

By using the gmaps4rails wiki and leveraging a modified version of an answer from a question on stackoverflow (Google Maps for Rails - update markers with AJAX), I have come very close to achieving my goal. The solution works almost perfectly, but there is a minor hitch. Below is an excerpt of how it currently operates:

sightings_controller.rb


// Controller code here

search.html.haml


// HTML code here

search.js.erb


// JavaScript code here

map.js


// More JavaScript code here

The issue I'm encountering revolves around handling the markers when the user pans and zooms without changing the search result. Ideally, I want to avoid calling the "resetMarkers" function in these instances to prevent a flicker of markers on the screen. However, my attempts to achieve this have been unsuccessful so far.

I experimented with creating additional variables to compare old and new marker values, but encountered challenges with maintaining their state throughout the page lifecycle. Another approach involved resubmitting the old hash as a parameter with each search request and setting a flag, but this method felt convoluted.

If anyone has insights on a more effective approach or if there's something crucial I'm overlooking, your input would be greatly appreciated. Thank you!

Answer №1

Your issue arises from the comparison of two lists of markers to determine whether an update is necessary.

The challenge is that even though

_.isEqual(__oldmarkers, __markers)
conducts a thorough comparison, there could still be changes in Marker instances within your list, such as IDs or timestamps, that differ for identical points.
Alternatively, it's possible that initially both __markers and __oldMarkers are both null, making them equal and preventing entry into the if block.

In my opinion, conducting a deep comparison here might be too resource-intensive. A better approach would be to compare easily comparable elements, like the flat list of coordinates for each set of markers.

You could try something along these lines:

var __markers, __coordinates = [];
function resetMarkers(handler, json_array) 
{
  var coordinates = _.map(json_array, function(marker) {
    return String(marker.lat) + ',' + String(marker.lng);
  });

  if(_.isEqual(__coordinates.sort(), coordinates.sort()))
  {
    handler.removeMarkers(__markers);
    clearSidebar();
    clearZipcode();
    if (json_array.length > 0) 
    {
      __markers = handler.addMarkers(json_array);
      _.each(json_array, function(json, index){
        json.marker = __markers[index];
      });
      createSidebar(json_array);
    }
    __coordinates = coordinates;
  }
};

In this solution, both __coordinates and coordinates are simply arrays of strings, which can be quickly compared to provide the desired outcome.
To facilitate the comparison using _.isEqual, both arrays are sorted beforehand.

NB: The old code utilized _.difference, but that proved to be incorrect (refer to comments for further discussion)
(Note that I'm opting for _.difference, potentially more resource-intensive than _.isEqual but offering the benefit of independence from the order of returned markers.)

edit: Also, you can now cease including "oldHash" in the search query parameters ;)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Access your account and modify the div section to display a personalized greeting like "welcome $username"

I am currently using a div element to show the user, password, and login button. Additionally, I have implemented AJAX to notify users of an "invalid login" without having to refresh the page. What I am trying to achieve is: Upon successful login, hide ...

Selection auto-closing feature

I am currently working on a button that generates a dropdown menu with various categories to choose from. I would like the dropdown to automatically close when I click outside of it, similar to how a lightbox or modal popup works on a webpage. Currently, I ...

Enhance the appearance of your custom Component in React Native by applying styles to Styled Components

I have a JavaScript file named button.js: import React from "react"; import styled from "styled-components"; const StyledButton = styled.TouchableOpacity` border: 1px solid #fff; border-radius: 10px; padding-horizontal: 10px; padding-vertical: 5p ...

When making a Wordpress ajax call, I am finding that the response is returning the entire page content instead

I've searched through numerous other questions related to this issue, but none of them are providing the solution I need. Despite simplifying my code to its most basic form for this exercise, I am still unable to pinpoint the error. I have spent hours ...

Ways to guarantee a distinct identifier for every object that derives from a prototype in JavaScript

My JavaScript constructor looks like this: var BaseThing = function() { this.id = generateGuid(); } When a new BaseThing is created, the ID is unique each time. var thingOne = new BaseThing(); var thingTwo = new BaseThing(); console.log(thingOne.id == ...

What is the method to obtain the URL of the most popular tweet related to a hashtag using node.js?

I'm currently working on creating a Discord bot that can display the top tweet for a specific hashtag upon request. However, I've hit a roadblock as I can't seem to find information on how to search for tweets using a hashtag in the Twitter ...

Detect mousewheel movement in jQuery/JS without causing the page to scroll

Is there a way to detect if the mousewheel is triggered and determine whether it's scrolling up or down without actually moving the page (body with overflow: hidden)? Any suggestions on how I can accomplish this using jQuery or pure JavaScript? $( ...

Dynamically loading Ember templates with asynchronous requests

I need a way to dynamically load HTML content from another file using the code below: App.MainView = Ember.View.extend({ template:function(){ $.ajax({ url: 'views/main.html', dataType: 'text', async: false, ...

Creating Highcharts using data fetched from an Ajax call

I'm receiving an array of data from ajax responses that looks like this: [ { "name":"online", "data":["34","155","12"] }, {"name":"ofline", ...

Webpack simplifies the process of automatically loading external dependencies

Exploring the options available, I am curious if there is a more sophisticated approach to this issue. In the process of developing a Webpack application, it is typical to have dependencies that do not require compilation/bundling, such as jQuery, React, R ...

What causes my ready function to consistently execute upon controller or directive reinitialization?

Every time my controller or directive reinisilize, the angular.element(document).ready(function(){...}); function is executed. Why does this happen? In my scenario, I have two controllers and one directive. I update a value in the parent controller which ...

Navigating an array like a pro / Unraveling the mystery behind click event targets

Currently, I am working on implementing an Add to Favorite feature. When I click on an icon, the breed next to that icon gets added to the likes array. I have created a renderLikes function to display the contents of the array on the screen. However, only ...

What would be a colloquial method to retrieve the ultimate result from the iterator function?

I've got a rather complex function that describes an iterative process. It goes something like this (I have lots of code not relevant to the question): function* functionName( config: Config, poolSize: number ): Generator<[State, Step], boo ...

Setting Django form value to match another form value in template

In my quest to achieve a specific objective, I am faced with the challenge of having two forms, form1 and form2, within a single view. The models associated with these forms are as follows: Class Model1(models.Model): var_1=models.CharField() var_2=mode ...

choose user by ticking the checkbox

For each user in the table, I aim to create a checkbox. Here is my tableBody: <TableBody> {users.map((user) => { return ( <TableRow key={user.id}> <TableCell padding="checkbox"> <Checkbox ...

The print function is being triggered before the partial view

My goal is to open a partial view in a new window and call the print function, but I'm facing an issue where the partial view renders after the print function, resulting in a blank page. I attempted using the $timeout function, but encountered the sam ...

Using JQuery to find the nearest element and narrowing down the search to its child elements

In my program, I have 3 forms identified by form1, form2, and form3. Each form contains its own set of dropdown lists named drop1 and drop2, along with a submit button. When the submit button is clicked in any form, it checks which option was selected from ...

What is the best way to search for all results in MongoDB that have x appearing in any property?

Is it possible to search for all pictures in the mongoose framework with node and express that contain a specific parameter, regardless of which property holds that parameter? For example: If I enter "John Snow" in the search bar, I want to see all pictur ...

Leverage the hidden glitch lurking within Vue

While working with SCSS in vue-cli3, I encountered a strange bug where using /deep/ would result in errors that I prefer not to deal with. Code Running Environment: vue-cli3 + vant + scss CSS: /deep/ .van-tabs__content.van-tabs__content--animated, .va ...

The recursion in the Lodash function has gone beyond the stack size limit

The objective I have set out to develop a unique "deepMapValues" function. This function is designed to take a specified function and an object, apply the function to each value in the object deeply, and return the modified object accordingly. (v, k) => ...