lmiguelvargasf
lmiguelvargasf

Reputation: 69755

How to send latitude and longitude to django server using AJAX

I am using django, and I need to send the latitud and longitud using AJAX every time I click on an element.

This is what I have in my template:

{% block js %}
    <script>
      var latitud;
      var longitud;

      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(
            function (position) {
              console.log('Position has been set successfully');
              latitud = position.coords.latitude;
              longitud = position.coords.longitude;
          }, function (error) {
              console.log('Position could not be obtained.')
          });
      }
      dataToSend = {
          "fbpost": $("input[name=fb-post]").is(':checked'),
        "latitude": latitud,
        "longitude": longitud
      };

      var csrftoken = "{{ csrf_token }}";

      function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }

      $.ajaxSetup({
        beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
        }
      });

      $.ajax(
        {
          type: "POST",
          dataType: 'json',
          url: {% url 'pledges:home' %},
          data: JSON.stringify(dataToSend),
          success: function (msg) {
            console.log('Succeeded!');            
          },
          error: function (err) {
            console.log('Error!');
          }
        });
    });
  </script>
{% endblock %}

However, when I try to get the value of latitud in my view, I am getting an error as it was not sent:

KeyError: 'latitude'

This is the code I have in my view:

@login_required
def home(request):
    request_body = json.loads(request.body.decode('utf-8'))
    print(request_body['latitude'])

    # mode code

    return render(request, 'pledges/home.html', context)

How can I achieve this, I know that getting the latitud and the longitud is something asynchronous, but I have no idea how to deal with this situation.

Upvotes: 1

Views: 630

Answers (1)

James
James

Reputation: 22247

You're right, it's an ajax/async issue. Everything that uses the result of getCurrentPosition should be either in that callback function, or split out into a new function that gets called by the callback. Your reusable functions can be moved outside so they are globally scoped in case you need to use them again. For example:

{% block js %}
    <script>
      function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }

      $.ajaxSetup({
        beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
          }
        }
      });

      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(
          function (position) {
            console.log('Position has been set successfully');

            dataToSend = {
              "fbpost": $("input[name=fb-post]").is(':checked'),
              "latitude": position.coords.latitude,
              "longitude": position.coords.longitude
            };

            $.ajax({
              type: "POST",
              dataType: 'json',
              url: {% url 'pledges:home' %},
              data: JSON.stringify(dataToSend),
              success: function (msg) {
                console.log('Succeeded!');            
              },
              error: function (err) {
                console.log('Error!');
              }
            });
          }, function (error) {
              console.log('Position could not be obtained.')
          }
        );
      }
  </script>
{% endblock %}

Upvotes: 2

Related Questions