Handy Wrapper to deal with page load / Load order issues

Comments

6 comments

  • Avatar
    Keith Sterling

    Here's another approach to the same problem that I think might be simpler.  Page render always fires after all views have rendered, so use that event to trigger a jquery deferred in the view event, like this... 

    var pageRendered = $.Deferred();

    // FIRST VIEW EVENT
    $(document).on('knack-view-render.view_1', function(viewEvent, view, data) {
      // Wait for all views to render
    pageRendered.then(function(pageEvent, page) {
    // Do stuff here
    });
    // Other code that doesn't wait for page-render here
    });

    // ANOTHER VIEW EVENT
    $(document).on('knack-view-render.view_2', function(viewEvent, view, data) {
      // Wait for all views to render
      pageRendered.then(function(pageEvent, page) {
        // Do stuff here
      });
    // Other code that doesn't wait for page-render here
    });

    $(document).on('knack-page-render.page_1', function(event, page) {
    pageRendered.resolve(event, page);

    });

     

    This keeps the normal flow and I think is easier to read.  It also lets you use the page event's parameters (pageEvent and page) inside the view event.

     

  • Avatar
    Justin

    I didn't know that about page render_ Nice to know. I'll try this out next time I run into this problem

     

  • Avatar
    Brad Stevens

    Justin & Keith - really appreciate you sharing this with the community.

    Great work.

  • Avatar
    Justin

    Thanks Brad -I've learned a lot by piggybacking on the code you have shared here and appreciate the feedback.

    If you have a minute maybe you can help me with this code. ?  I would really appreciate it.

    I want to create an easy way to record the record.id for every record created in my database.

    The idea is a create an array of objects  that stores what views/scenes are associated with which fields to record a record.id. Here's the code. As new  forms are added to the app  -you could just add a new entry to the array and automatically be saving the record.id for each new record.

    It works when the payload field value is represented as text ( field_317) but I cannot get it to work when it is represented as a var  (field_name) (even though I'm able to console.log that value in the same function.)

    You can see below that I'm able to log the value on the lines directly preceding and following the declaration of the payload.  I think if I can get that last part working this will be a very useful script for the community. Allowing the easy transfer of connection fields between objects and easily parsing urls for custom view links to your records.

     


    //Record all record ids for every record created
    //create an array of objects representing which view creation scenex/views correspond to which record.id fields
    bindListToInputs([
    {
    //object is client
    page_name: "page_14",
    field_name: "field_317", //field to capture record ID
    view_name: "view_15",
    },

    //repeat as necessary

    {
    //a different record create screen
    page_name: "page_186",
    field_name: "field_317",
    view_name: "view_308",

    }
    ]);

    function bindListToInputs(list){
    list.forEach(function(inputs){
    bindToInputs(inputs);
    });
    }

    function bindToInputs(inputs){

    var page_name = inputs.page_name,
    view_name = inputs.view_name,
    field_name = inputs.field_name;

    $(document).on("knack-record-create." + view_name, function(event, view, record) {

    console.log('record created');
    console.log(view_name, record.id);

    var url = "https://api.knack.com/v1/pages/" + page_name + "/views/" + view_name + "/records/" + record.id;

    console.log (url, field_name);  //correctly logs 'field name ' here


    var user = Knack.getUserToken();
    var headers = { "Authorization": user, "X-Knack-Application-ID": app_id, "Content-Type":"application/json"}

    //var data = { field_name: record.id };    //this does not work
    var data = { field_317: record.id };         //this does, why?
    console.log (url, field_name);  //correctly logs 'field_name' here

    Knack.showSpinner();
    // Make the AJAX call
    $.ajax({
    url: url,
    type: 'PUT',
    headers: headers,
    data: JSON.stringify(data),
    }).done(function(responseData) {
    console.log('Record updated!');
    Knack.hideSpinner();
    });
    });

    }

  • Avatar
    Brad Stevens

    Hi Justin,

    I'm no JavaScript or JSON expert, but it seems to me the problem is using a variable as the property name in building your JSON data object.  I'm pretty crunched for time at the moment but it wouldn't surprise me if a bright spark on Stackoverflow has already answered this problem already:

    "How to build a JSON object using a variable as the property name..."

    Anyone else?

  • Avatar
    Justin

    Thanks, Brad. I figured it out with a little help from stack overflow.

    Here's the code in case anyone is interested. In the future, I plan on adding this to every app I build and to create a field to record the record.id for each object. This way if I want to send a link to a specific record in a Knack generated email it can be generated via text formula in the background and included in the notification (even if there is a parent's record.id in the url string.)

    //Record a record.id for every record created

    //create an array of objects
    bindListToInputs([
    {
    //object is client
    page_name: "page_14",
    field_name: "field_317", //field to capture record ID
    view_name: "view_15",
    },
    //repeat as necessary
    {
    //Another view where a different object record is created
    page_name: "page_186",
    field_name: "field_317",
    view_name: "view_308",
    }
    ]);

    function bindListToInputs(list){
    list.forEach(function(inputs){
    bindToInputs(inputs);
    });
    }

    function bindToInputs(inputs){

    var page_name = inputs.page_name,
    view_name = inputs.view_name,
    field_name = inputs.field_name;

    $(document).on("knack-record-create." + view_name, function(event, view, record) {

    console.log('record created');
    var recordOne = record.id
    console.log(view_name, record.id);

    var url = "https://api.knack.com/v1/pages/" + page_name + "/views/" + view_name + "/records/" + record.id;

    //console.log (url, field_name);

    var user = Knack.getUserToken();
    var headers = { "Authorization": user, "X-Knack-Application-ID": app_id, "Content-Type":"application/json"}
    var fieldnamed = field_name
    var data = {};
    data[fieldnamed] = recordOne


    //console.log('data is : ', data);
    //console.log (url, field_name);

    Knack.showSpinner();
    // Make the AJAX call
    $.ajax({
    url: url,
    type: 'PUT',
    headers: headers,
    //data: data,
    data: JSON.stringify(data),
    }).done(function(responseData) {
    console.log('Record updated!');
    Knack.hideSpinner();
    });
    });

    }

Please sign in to leave a comment.