-1

I have a script that loads additional data and gives extra functionality to multiple elements of a view. I like to take a more OPP aproach to do this so i have "classes" build for my entities. The problem i am facing right now is that the informations comes from server side so I need that data before I can give functionality.

On my script I have three Objects User, Prospect and ProspectDetailView.

so I work in this way.

$(document).ready(function _document_ready() 
{

//*
ajaxStatus.showStatus('Cargando información adicional...');
var promotor        = new User();
var prospecto       = new Prospect($("input[name=record]").val());
var vistaDetalle    = new ProspectDetailView();



vistaDetalle.drawAditionalStatusTag(prospecto.data);
vistaDetalle.drawGroupDataField(prospecto.inscription);
vistaDetalle.drawInscriptionDifferences(prospecto.data, prospecto.inscription);
vistaDetalle.drawPendingRequestTag(prospecto.inscription.requests);
vistaDetalle.drawPendingTicketTag(prospecto.inscription.tickets);
vistaDetalle.drawTicketsHistoryPanel(prospecto.inscription.tickets_h);

ajaxStatus.hideStatus();
//*/ 
});//#END _document_ready()

As you can see create a User then a Prospect and finaly load my View Object.

Problem is that I need the data from the prospect (mandatory) before I can work with the view.

I load my Prospect like this

// Definiciones de la información del prospecto.
var Prospect = function (uuid){
this.uuid = uuid;

var __init__ = function (self)
{
    $.ajax({
        type    : "POST",
        dataType: "json",
        data    : {"confirm" : true },
        "context": self,
        "async" : false,
        url     : dev()+'/crmutilidades/get_inscription_data/'+self.uuid+'/'+module_sugar_grp1,
        success : function _success_get_inscription_data(response) 
        {
            this.inscription = response.data;
            this.data = response.data.prospect;
            this.paid = response.data.inscrito !== 'undefined' ? response.data.inscrito : false;
        }
    });
}
__init__(this);

}//#END Prospect

I need to use the async false in order to retrieve the prospect data before i can use it in the view object, and it works, but can't stop the feeling that it's a nasty hack or wrong.

So I tried to use $.when (promises i guess are called)

and did this:

 prospect = null;
    user = null;
    $.when(prospect = new Prospect(), user = new User).then( function(){
    view = new ProspectDetailView();
    ...Do all view calls.
});

Hoping that the view will execute when the prospect and user finish loading but i fail. I get the same error . prospecto is undefined, because everything is async.

How should I model that. As far as I can tell i need to directly pass ajax calls to the $.when method but that would defeat the purpose to have my entities separated and isolated from one another.

Neto Yo
  • 450
  • 1
  • 5
  • 17
  • *"but can't stop the feeling that it's a nasty hack or wrong."* Great, because it is! the next step is to make sure that you actually have a promise to work with. $.ajax returns one, so you should present it as a property of the Prospect instance so that you can use it in a $.when. – Kevin B Mar 17 '16 at 19:58
  • I get you care to provide an example, i guess you mean to do a property called this.load = $.ajax({}), then explicitely do $.when(Prospect.load, user.load).then(stuff); I'll try that but i dónt like the idea of explicitely calling the load thing i though the __init__ constructor like method was better. – Neto Yo Mar 17 '16 at 20:02
  • Your `Prospect` and `__init__` functions don't return anything, so there's no promise to await. However, they probably should not either, have a look at [Is it bad practice to have a constructor function return a Promise?](http://stackoverflow.com/a/24686979/1048572) – Bergi Mar 17 '16 at 20:03

1 Answers1

0

You could use a Promise.

var prospect_created = new Promise(function(resolve, reject){
    // any necessary setup
    $.ajax({
        success: resolve,
        error: reject,
       // etc
     })
})

create_prospect.then(function(prospect){
 // create your view using the prospect
})

By passing resolve as the success parameter to your ajax request, whatever is returned from the ajax request will be the argument to the function you pass to the promise object's .then method.

Jake
  • 165
  • 8
  • `Promise`, "native" and "HTML5" have nothing to do with each other. – Bergi Mar 17 '16 at 21:15
  • Don't use the `Promise` constructor to create ajax promises, see [here for how to do it correctly](http://stackoverflow.com/a/31327725/1048572) – Bergi Mar 17 '16 at 21:17