1

I have a map search page on my site. I'm able to display all the locations in a list in HTML but I am struggling to pass the locations to JavaScript at the same time in order to populate the pins on my Google map.

I only seem to be able to get wp_localize_script to work on the initial page load and during the AJAX call.

This is my javascript:

jQuery(document).on( 'submit', '#locationsearch', function() {
    var form = jQuery(this);
    var input = form.find('input[name="postcode"]');
    var query = input.val();
    var map=jQuery('#map');
    var content = jQuery('#results');

    jQuery.ajax({
        type : 'post',
        url : myAjax.ajaxurl,
        data : {
            action : 'getStockistLocations',
            query : query
        },
        beforeSend: function() {
            console.log('fetching');
            input.prop('disabled', true);
            content.addClass('loading');
        },
        success : function( response ) {
            console.log(myAjax.locations);
            input.prop('disabled', false);
            content.removeClass('loading');
            map.removeClass('hide-map');
            content.html( response );
        }
    });

    return false;
});

My console.log(myAjax.locations) keeps returning "undefined".

Here is my PHP function:

public function getStockistLocations(){
        $postcode = $_POST['query'];

        $geocode=new Geocoder();
        $lnglat = $geocode->geocodePostcode($postcode);

        $results=$this->getStockists($lnglat);
        if( !empty($results) ) {
            wp_localize_script( 'main', 'myAjax.locations', $results );
            ob_start();
            foreach ($results as $result){
                global $locationresult;
                $locationresult=$result;

                get_template_part('template_parts/cards/card','location');
            }
            $content = ob_get_clean();

            echo $content;
        }

        die();
    }

I'm localizing my script in another class:

protected function localizeScripts(){
        global $post;

        $mappages=[
            'contact',
            'where-to-buy',
            'find-an-installer'
        ];

            if(in_array($post->post_name,$mappages)){
                $payload=array(
                    'url'   =>  get_stylesheet_directory_uri(),
                    'ajaxurl'  =>  admin_url('admin-ajax.php'),
                );

                wp_localize_script( 'main', 'myAjax', $payload );
                $key=$this->getAPIKeys('google');
                wp_enqueue_script('gmap','https://maps.googleapis.com/maps/api/js?key='.$key.'&callback=initMap',null,false,true);
        }
    }

What am I missing?

1 Answer 1

1

It looks like you attached your localised script to the main script, but you don't enqueue the main script, you enqueue gmap.

I also notice you use the legacy/antiquated Admin AJAX interface. Have you considered using the modern REST API interface instead?

Also consider that your AJAX should be returning raw data. By returning raw HTML instead, you open yourself to security issues, and limit the possibilities for caching. Fetch data then generate the markup in the browser using JS instead

Finally, you can't call wp_localize_script( 'main', 'myAjax.locations', $results ); inside an AJAX response, it doesn't make sense. Localising a script attaches that data if main is enqueued, but it doesn't make sense to enqueue a script or style in an AJAX request as no scripts or styles get printed out ( you need a wp_head call for that, and those don't belong in AJAX requests either ).

A work around would be to put it in a script tag and assign it to a variable on window, but then you would need special handling to execute that javascript on the browser side, making the prior mentioned security problem even worse.

So instead:

  • fetch raw data from the site, not HTML, ideally JSON encoded
  • generate the UI in javascript in the browser, don't blindly accept arbitrary hunks of HTML generated by PHP

By doing those 2, most of your problems will be sidestepped entirely, your application will be faster, and your code will be safer.

2
  • 1
    I had no idea there was a REST API... I'll go research that now.
    – Burgi
    Commented Oct 21, 2019 at 14:50
  • Basically everything underneath /wp-json
    – Tom J Nowell
    Commented Oct 21, 2019 at 18:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.