Alpine.js

Das Framework alpine.js ist sehr nützlich um interaktive Frontend-Seiten schnell und sauber hin zu bekommen. Wenn man jedoch einen AJAX Call durchführen möchte und und aus irgendwelchen Gründen kein .fetch() nutzen kann, muss man auf das bekannte XMLHttpRequest() Objekt zurück greifen. Innerhalb des Responses eines solchen Calls, kann man jedoch nicht mehr per this auf die Alpine.JS Modul-Instanz zurück greifen.

Dafür gibt es aber einen Workaround um das aktuelle Alpine.js Modul global verfügbar zu machen. Der Trick ist this im Modul Context auf ein window Objekt zu schreiben im init()

Mini Beispiel zur Verdeutlichung:

// dummy data
function alpinejs_dummy_ajax_app(){
	return {
		'dummy_data' : false,
		init() {
			window.this_alpinejs_module = this; // makes it globally available
			change_data_in_alpinejs_module();
			console.log( this.dummy_data ); // --> true
		}
	}
}
 
// This could be a new XMLHttpRequest() success-handler
function change_data_in_alpinejs_module(){
	window.this_alpinejs_module.dummy_data = true;
}

Im Beispiel mit dem Ajax call sieht es dann so aus:

function alpinejs_dummy_ajax_app(){
 
	return {
		'dummy_data' : function() {
			return { 
				'dummy_json' : 'Data 123' 
			};
		},
 
		'repsonse_json' : false,
 
		'submit_data' : function() {
 
			// PREPARE AJAX POST
			const ajax_post_url =  'https://www.example.com/api-endpoint'; 
			const xhttp         = new XMLHttpRequest();
			xhttp.open( 'POST', ajax_post_url, true );
			xhttp.setRequestHeader("Content-Type", "application/json");
			xhttp.onreadystatechange = function() {
				const is_call_success = (this.readyState == 4 && this.status == 200) ? true : false;
 
				if( is_call_success ) {
					const response_json = JSON.parse( this.response );
					/*
 					    in current context 'this' would refer to the XMLHttpRequest Object
					    we need to write the response data to the alpine.js object.
					    So we be bound the current alpine.js object to a global window variable
					*/
					window.this_alpinejs_module.repsonse_json = response_json; // working version of this.repsonse_json
 
					return true;
				}
			};
 
			// DO THE AJAX POST
			const data = JSON.stringify( this.dummy_data() );
			xhttp.send( data );
		},
 
		init() {
			/*
			    This makes the alpine.js object available out of 'this' current context.
			    e.g. for methods in other objects
			*/
			window.this_alpinejs_module = this; // <-- I M P O R T A N T
		}
	}
}

Page Tools