Software Archive
Read-only legacy content
17061 Discussions

Help: xdkFilter proper implementation

Waleed_H_
Beginner
279 Views

Hi,

 

I wonder what is the proper method to implement xdkFilter function to deal with web service results? For example:

- Best location to place the code? separate file? index_user_scripts?

- if index_user_scripts, would I place it within the (function() {..... or the function register_event_handlers() {.... or a separate new function body?

- Should I pass all the result params or just those I want to alter?, i.e. xdkFilter: myFunction(param1, param2, param3) or xdkFilter: myFunction(param2) or myFunction(Result_Object_As_Received)?

- If I want to alter for example 3 params, what is the best way to return them after alteration?

- Should the params be returned in their exact names that came in the web service response and showing in the {{mustache}} or any name? should I then use the new names in the {{mustache}}?

- Finally, if it is needed to process let's say 2 params that came from the web service to generate a new var, how can I return this var and how to link it using the designer? i.e. I received the user age and gender from server database (web service), and I want when showing the results in the ListView widget to show the proper silhouette image of a young female or old male...etc.

Thanks :)

 

0 Kudos
1 Solution
Chris_P_Intel
Employee
279 Views

You can put the function where ever you want. Javascript doesn't have proper namespaces, so if you are inside the scope of some other function you'll need to make sure to expose it.  Putting in in index_init_services.js would be the simplest  (not index_user_scripts.js)

Should I pass all the result params or just those I want to alter?, i.e. xdkFilter: myFunction(param1, param2, param3) or xdkFilter: myFunction(param2) or myFunction(Result_Object_As_Received)?

You can pass other options to the _service_ call.  But the xdkFilter only receives one argument: the data after it has been returned by the web service.  

Are you using App Designer?  If so, try this to help understand what's going on:

  • from within App Designer find your service binding in the Service Methods panel.
  • Click on your binding and look at the Request tab
  • You should see the original service method arguments listed there.  Modify one of them. (Let's imagine your service has a num_results param, and you change it from 20 to 7).
  • Now open index_init_services.js  .  You'll see something like this:
  • data_support.ready(intel.xdk.services.rottentomatoessearch.bind(null, {"num_results":7, "xdkFilter":null}));

See where "num_results" ended up?  That's where you can change the other options.  

If you want to call the service yourself with new options, it is easy to do:

intel.xdk.services.rottentomatoessearch( {"num_results":500}).then(function(data){ 
  console.log("here come 500 results:", data); 
  //there is also an event posted with the data.
})

The xdkFilter function takes one argument (the data) and should return one result (the modified data).  It can be used to filter or adjust the data. This is especially useful because if you are using a service method with Angular or Backbone, then those things are listening to an event with the data.  The xdkFilter function will make sure that when the event is posted, it gets your filtered data.

Finally, if it is needed to process let's say 2 params that came from the web service to generate a new var, how can I return this var and how to link it using the designer? i.e. I received the user age and gender from server database (web service), and I want when showing the results in the ListView widget to show the proper silhouette image of a young female or old male...etc.

Cool!  This is easy.  First, in index_init_services.js  we'll need to provide an xdkFilter function.  For this example code I'm just going to pretend that data that is the response, has a field called "people" which is an array of people I want to extend

var male_avatar_path = "images/avatars/male.png";
var female_avatar_path = "images/avatars/female.png";

function modify_people_response(data)
{
  data.people = _.map(data.people, function(person){ 
   //add new avatar property to person entry
   person.avatar = (person.gender == "male") ? male_avatar_path : female_avatar_path;
   })
  return data; 
}

data_support.ready(intel.xdk.services.getthepeople.bind(null, {"xdkFilter":modify_people_response}));

 

Ok, now we've added a new avatar property to each person.    So, in App Designer you are using Backbone the token for this would be {{avatar}}, if using Angular it'll be {{entry.avatar}}  .  This mustache variant will not be in the list that App Designer shows you when using data driven controls - it only knows about values that you put checkmarks next to when making the service. But that makes it no less valid.  Any property in the data is addressable.  So just insert that token where you need it.

 

Does this help?

Chris

View solution in original post

0 Kudos
2 Replies
Chris_P_Intel
Employee
280 Views

You can put the function where ever you want. Javascript doesn't have proper namespaces, so if you are inside the scope of some other function you'll need to make sure to expose it.  Putting in in index_init_services.js would be the simplest  (not index_user_scripts.js)

Should I pass all the result params or just those I want to alter?, i.e. xdkFilter: myFunction(param1, param2, param3) or xdkFilter: myFunction(param2) or myFunction(Result_Object_As_Received)?

You can pass other options to the _service_ call.  But the xdkFilter only receives one argument: the data after it has been returned by the web service.  

Are you using App Designer?  If so, try this to help understand what's going on:

  • from within App Designer find your service binding in the Service Methods panel.
  • Click on your binding and look at the Request tab
  • You should see the original service method arguments listed there.  Modify one of them. (Let's imagine your service has a num_results param, and you change it from 20 to 7).
  • Now open index_init_services.js  .  You'll see something like this:
  • data_support.ready(intel.xdk.services.rottentomatoessearch.bind(null, {"num_results":7, "xdkFilter":null}));

See where "num_results" ended up?  That's where you can change the other options.  

If you want to call the service yourself with new options, it is easy to do:

intel.xdk.services.rottentomatoessearch( {"num_results":500}).then(function(data){ 
  console.log("here come 500 results:", data); 
  //there is also an event posted with the data.
})

The xdkFilter function takes one argument (the data) and should return one result (the modified data).  It can be used to filter or adjust the data. This is especially useful because if you are using a service method with Angular or Backbone, then those things are listening to an event with the data.  The xdkFilter function will make sure that when the event is posted, it gets your filtered data.

Finally, if it is needed to process let's say 2 params that came from the web service to generate a new var, how can I return this var and how to link it using the designer? i.e. I received the user age and gender from server database (web service), and I want when showing the results in the ListView widget to show the proper silhouette image of a young female or old male...etc.

Cool!  This is easy.  First, in index_init_services.js  we'll need to provide an xdkFilter function.  For this example code I'm just going to pretend that data that is the response, has a field called "people" which is an array of people I want to extend

var male_avatar_path = "images/avatars/male.png";
var female_avatar_path = "images/avatars/female.png";

function modify_people_response(data)
{
  data.people = _.map(data.people, function(person){ 
   //add new avatar property to person entry
   person.avatar = (person.gender == "male") ? male_avatar_path : female_avatar_path;
   })
  return data; 
}

data_support.ready(intel.xdk.services.getthepeople.bind(null, {"xdkFilter":modify_people_response}));

 

Ok, now we've added a new avatar property to each person.    So, in App Designer you are using Backbone the token for this would be {{avatar}}, if using Angular it'll be {{entry.avatar}}  .  This mustache variant will not be in the list that App Designer shows you when using data driven controls - it only knows about values that you put checkmarks next to when making the service. But that makes it no less valid.  Any property in the data is addressable.  So just insert that token where you need it.

 

Does this help?

Chris

0 Kudos
Waleed_H_
Beginner
279 Views

Wonderful Chris. Thanks a lot for your help :)

0 Kudos
Reply