I could see certain errors already mentioned in your code, but omiting those mistakes you say you get a JSON still, so we omit this and concentrate on the result.Let's remember something, AJAX is asynchronous, this means it will take a while to return an answer or a mistake, as we well know javascript runs on a single thread always, and no, there's no way he runs in several threads, the nature of javascript It is to be monohilo.This means anything that is detected asynchronous SI it will run, but javascript what it will do is to make it run and while you get an answer you will continue to execute the code you find LATER from the call to AJAX.I mean, javascript He's not gonna wait till AJAX return a value, just let it run and keep running the rest.This doesn't happen for synchronous operations.Knowing this, it's normal to catch up on trying to get the property back. events of your object undefined since it means that AJAX He hasn't returned an answer yet.So how do we manage to pass to the object the value obtained by AJAX?Well... to say first that what you had in your original code was not a function, it was an object, so being an object we can't make use of async - await directly inside him.You are also having a technical failure when trying to 'back' the response AJAX since although AJAX complete your answer, you're never really returning it out, I explain why:$.ajax({});
That's a call to AJAX in his least expression, in this expression, even if it is a useless call, we can see it clearly, what we pass to him AJAX It's a objeto, seeing your example you have as one of the properties of this object the property successWhich is normal:success:function(msg){
console.log(msg);
result = msg;
return msg;
//callback(msg);
}
But keep in mind that in JS We have this called scope or bloque which refers to any space delimited between keys {} (literally any), so when you do return you are not returning to the function obtenerEventos, you are returning to the function successThat you know doesn't make sense.So I propose to you something, to promote AJAX, since you try what you try, do whatever you do, You don't. or at least You shouldn't. change the nature of AJAX to be asincrona to become sincrona, since if you do it you can generate several types of unwanted errors.So I'll say one thing that's going to saddle you up a bit, but it's for the good of us programmers (and this is not for convenience, if not because there's simply no more options):There is no way to directly use the return value of an asynchronous function, as these always do what you do return something called Promise.To obtain the values contained in a Promise, there are only two options, one is limited to using an asynchronous function to use the word reserved. await and force the code to wait for it resuelva or rechace the promise (that returns us either the value or an error), in this way we simulate that AJAX be synchronous.However as you have it is an object and not a function this option would not be the most appropriate... the other option resides simply instead of using the value directly, return the Promise whole (as it contains the data) and use .then and .catch of the promise to use their value wherever you need to use them then:So what I propose is this:function obtenerEventos(id){
return new Promise((res, rej) =>{
$id = id;
$.ajax({
type:"POST",
url:"<?php echo Router::url(array('controller' =>'CalendarioPlantillas', 'action' => 'eventosGerencia')); ?>",
headers : {
'X-CSRF-Token': $('[name="_csrfToken"]').val()
},
data:{
idcentro:$id
},
beforeSend: function(xhr)
{
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
},
success:function(msg){
console.log(msg);
result = msg;
res(msg);
//callback(msg);
},
error:function(xhr, textStatus, errorMessage){
//alert("Ha ocurrido un error inesperado intentelo de nuevo");
console.log(errorMessage);
console.log(textStatus);
console.log(xhr);
rej(errorMessage);
}
});
});
}
As we see, we've locked up your code. AJAX inside a Promise, this result is called promisingBesides changing your return for res or rej that are the callback that receives a promise for the management of return valor or errorWhich is why you could see it as returns customized within the promise.Now that's it promising a AJAXas I said before you will not be able to recover the value returned by the PromiseIf not you should use .then and .catch where you want to recover or use the Promise value, just like this:calendar.events.then(data =>{
//Obtenemos la data traida por AJAX, solo aquí dentro tendras acceso a la data
console.log(data);
}).catch(e)=>{
//Obtenemos el error traido por AJAX (solo en caso de error).
}
That would be the way to use what we had done before. Promisificar Your call AJAX, even if you want a shorter form and are within an asynchronous functionYou can cut it off to this:async function printEvents(){
const events = await calendar.events;
console.log(events);
}
Remember, await cannot be used in the global scope and is also only available within functions or methods that are asynchronous.Plus when we use Promises or funciones asincronas you have to forget the fact of trying to assign values directly to your variables that come from asynchronous code or asynchronous functions, since you do what you do. You won't be able.You must forget to try to "require" these values in another way to assign it to external variables so you don't have to use await, .then or .catch, since simply this is impossible for things that are asincronasThat's how the world works. asincrono.