0

I am using JQuery 3.6 in a page.

I want to avoid unnecessary trips to the server, so I am using a data-attribute data-fetched to set a flag to determine whether the trip to the server should be made or not.

Here is the relevant line in my HTML markup:

<li><a class="nav-link" data-fetched="0" href="#foo" data-url="/some/path/endpoint" data-csrf="09i9i90203r30rce" data-toggle="tab">Tab One</a></li>

The Javascript code that handles this is shown below:

$().ready(function() {

    // Posts
    $('a.nav-link[data-url]').on('click', function(e){
        console.log('Element with href: ' + $(this).attr('href') + ' clicked!');

        let selected_elem = $(this);
        let fetched = parseInt( $(this).data('fetched') );
        let elem_to_update = $(this).attr('href');

        console.log('data-fetched attribute value: ' + selected_elem.data('fetched'));

        if (fetched == 1){
            console.log('Data already fetched from server')
        } else {

            $.ajax({
                type: 'POST',
                url: $(this).data('url'),
                headers: {
                    'X-CSRFToken': $(this).data('csrf'),
                  },            
                dataType: 'html',
                success: function(data, textStatus, jqXHR){
                    selected_elem.attr('data-fetched','1');
                    $(elem_to_update).html(data)
                },
                error: function (jqXHR, textStatus, errorThrown ) {
                    console.log(textStatus);
                    alert(" Can't do because: " + errorThrown);
                },                
            });
        }

    });

When I run this code, I always get the following output in the console:

data-fetched attribute value: 0

Why is the variable value not being correctly read in my script - even though it the HTML variable is being set correctly?

How do I fix this?

Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
  • `selected_elem.attr('data-fetched','1');` should be `selected_elem.data('fetched','1');` – epascarello Aug 23 '21 at 21:39
  • @epascarello Nope. The DOM and JQuery seem to be out of sync for some reason. The only way I could get this to work was to do this hack: ` selected_elem.data('fetched','1').attr('data-fetched','1'); `. If there is a better way of doing this, I'd like to know in an answer - otherwise, that seems to be the ony thing that works :/ – Homunculus Reticulli Aug 23 '21 at 21:42
  • 2
    It's working as intended. .data pulls from the element exactly one time, when you first call .data on that element. Any future calls to .data will not affect .attr, and similarly any future calls to .attr will not affect .data. Under normal circumstances, .data should simply be replaced with .attr across the board. – Kevin B Aug 23 '21 at 21:42
  • If you use **data** you cannot change its value with **selected_elem.attr('data-fetched','1');** – gaetanoM Aug 23 '21 at 21:42
  • You are referring to two different things... `data()` doesn't affect `data-* attribute`, `data-* attribute` doesn't affect `data()`. Please read the documentation. – Flash Thunder Aug 23 '21 at 21:47
  • basically, you should use .attr unless .attr can't do what you're looking to do, such as storing objects. but... any situation where you're storing data on dom elements, can be better handled by ***not*** storing data on dom elements. – Kevin B Aug 23 '21 at 21:49
  • When it comes to data attributes I'be generally found it easier and more consistent to ignore jQuery and just use native javascripts `.datset` – Jon P Aug 24 '21 at 00:10
  • There really is no reason why you would need to have the attribute with the correct value other than if you are looking at the source code. So reading and setting with data() should all you need. – epascarello Aug 24 '21 at 12:50

0 Answers0