Chain Webix Proxy Objects?

I want to access my REST backend and show some JSON data in a Webix Datatable.

  1. The backend requires authentication *AND*
  2. I need to change the received JSON data before showing it in the datatable.

How do I archive both? I know about the Webix REST proxy. I also found a solution to send the “Authroizsation” HTTP header. But how do I chain/combine that with the JSON reformatting?

I have several rest endpoints in the backend. All of them shall be shown in Datatables. All of them need authentication. But they all need DIFFERENT kinds of reformatting.

This is my current approach:

webix.proxy.authenticatingProxy = webix.extend({
        load: function(view, callback){
          var url = view.config.url.source;
          var token = 'Basic ' + btoa(username + ':' + password)   // btoa - base64 encoding
          console.log("GET", url, "Headers:", token)
          webix.ajax().headers({
            "Authorization" : token
          }).get(url).then(function(data){
            console.log("GET ", url,"returned", data.json())
            var records = data.json();
            webix.ajax.$callback(view, callback, "", records, -1);
          }).catch(logHttpError)
        }
      }, webix.proxy.rest);
    
      /* Proxy for fetching ideas from server 
           BUT THIS IS NOT CHAINED YET.  DOES NOT CALL authenticating Proxy
*/
      webix.proxy.ideasProxy = webix.extend({
        load: function(view, callback){
          var ideasUrl = "http://localhost:8080/liquido/v2/laws/search/findByStatus?status=IDEA";
          console.log("GET ideas")
          //view.config.url.source = ideasUrl
          webix.ajax().get(ideasUrl).then(function(data){
            var ideas = data.json()._embedded.laws;
            console.log("GET ideas returned", ideas)
            webix.ajax.$callback(view, callback, "", ideas, -1);
          }).catch(logHttpError)
        }
      }, webix.proxy.authenticatingProxy);

You could perhaps attach to the ‘onBeforeAjax’-event for the authentication?

I have done this in some of my code (In a webix 4.4 app):

webix.attachEvent(“onBeforeAjax”, function (mode, url, data, request, headers) {
headers[“Accept”] = “application/hal+json”;
if (undefined === headers[“Authorization”]) {
headers[“Authorization”] = "Bearer " + user.getAccessToken();
}
}

This way you no longer need the authenticatingProxy from your example.

-mads

I’ve got a solution I don’t know if this is the “intended webix way”, but at least it works :slight_smile:

One thing that i am struggling with is, that I do not want to have my URL in the configuration of the view component. The URL (that the proxy loads from) should be loaded from an external configuration file.

webix.proxy.ideasProxy = {
  $proxy: true,
  url: "http://localhost:8080/liquido/v2/laws/search/findByStatus?status=IDEA",
  token: 'Basic ' + btoa(username + ':' + password),   // btoa - base64 encoding,
  
  load:function(view, callback){
    console.log("Loading ideas ",this.url)
    webix.ajax().headers({
      "Authorization" : this.token
    }).get(this.url).then(function(data){
      console.log("received ideas", data.json())
      var ideas = data.json()._embedded.laws
      //$callback is undocumented:  https://forum.webix.com/discussion/4443/custom-proxy-documentation-have-not-enough-details
      webix.ajax.$callback(view, callback, ideas)
    })
  }
}

and Then in my DataTable

{
id: "ideas",
view: "datatable", select:true,
columns:[
  {id:"id", header:"ID", width:150},
  {id:"title", header:"Title", fillspace:true},
  {id:"description", header:"Description", fillspace:true, sort:"string" },
  {id:"numSupporters", header:"Supporters", width:95, sort:"int" },
  // {id:"book", header:"Booking", css:"webix_el_button", width:100, template:"<a href='javascript:void(0)' class='check_flight'>Book now</a>"}
],
url:"ideasProxy->"    // need the arrow!
}

There is also an ALTERNATIVE SOLUTION. Actually much simpler:

One can simply define a function for the URL parameter of the DataTable:

 url:function(){
            console.log("Loading ideas")
            var url = "http://localhost:8080/liquido/v2/laws/search/findByStatus?status=IDEA"
            var username = "username"
            var password = "xxxxxx"
            var token = 'Basic ' + btoa(username + ':' + password)   // btoa - base64 encoding            
            return webix.ajax().headers({
              "Authorization" : token
            }).get(url).then(function(data){
              console.log("received ", data.json())
              return data.json()._embedded.laws
            })
          }

This works. But from an architectural standpoint its not that nice. Authentication and username management should be done in one central place. That’s why I was experimenting with proxy objects in the first place.