Start a new topic

Sending addional parameters on fetching Elements

Hey,


i wanna create a post (or Pre?) Fetch Hook in my Businesslogic.

Case:
I want to fetch a collection and add some stuff to each model, based on another collection. I wanna parse some variables to the fetching, to know what i have to search for inside the other collection.

Problem:
I can't add params to the fetch method, so that i can work with them iniside the hook. The Request-Body is always empty as every other place. 


How is this possible?

Best, Nico


Hi Nico,


Fetch method translates to a GET API call which doesn't accept request body parameters.


You can write a custom endpoint for this requirement. The flow can be something as below:

  • Search on collection1.
  • Based on parameters in request body, search on collection2.
  • Merge the results and send the data back in response body.

Let me know if you have any follow up questions.


Regards,
Wani

Hey, thanks for that.

Jeah i have a custom endpoint before, but i wanna use the offline mechanics of Kinvey which does to only work correctly if i using the fetching method?

Best, Nico

Hi,


Which client side SDK are you using to interact with Kinvey?


Regards,

Wani

Backbone.js (inside titanium)



Best, Nico

Hi Nico,


There's no direct way to do this.


A workaround can be done similar as below:

  • In backbone application fetch code, attach a query object with contains for column "collection2" - documentation for contains is available here: http://devcenter.kinvey.com/backbone/guides/datastore#ArrayOperators
  • In preFetch code, get this value, use it to fetch data from the other collection.
  • Delete "collection2" from the query object. If you don't do this contains query will be applied to GET call on the originial collection.

To retrieve query object and delete contains, you can use following code snippet:

 

  var query = JSON.parse(request.params.query);
  // process using query.collection2 here
  // afterwards, proceed to deleting that parameter
  delete query.collection2;
  request.params.query = JSON.stringify(query);
  // response.continue

 

Try this out and let me know if this works for you.


Regards,
Wani

Hey Wani,


that works! :)

Question:
What is the best way to structure the script inside the "pre" Fetch method? Until now my script was a custom Endpoint so it returns the events directly. 

Returning a response.body inside the pre fetch isn't usefull or? To me it seems to make more sense to insert my stuff into the postfetch?

Best, Nico





 

var logger = modules.logger.info;
	var async = modules.async;
	var body = response.body;
	var collectionAccess = modules.collectionAccess;
	var moment = modules.moment;
	var today = moment();
	
	
	
	var query = JSON.parse(request.params.query);
	
	
	
	
	// userID
	var userID = query.column2.$in[0];
	
	// squadID
	var squadID = query.column2.$in[1];
	
	
	delete query.column2;
  request.params.query = JSON.stringify(query);
	

	logger("userID: " + userID);
	logger("squadID: " + squadID);
	
	// Query to find Eventsl
	var q_events = {
	  'squad._id' : squadID
	};
	
	
	
	/**
	 * Self executed Function
	 */
	(function(){
	  
	  var _opts = {};
	  if(request.body.skip){
	    _opts['skip'] = request.body.skip
	  }
	  if(request.body.limit){
	    _opts['limit'] = request.body.limit
	  }
	  
	  
	  // Only Dates that are coming (today, or in the future)
	  if( request.body.future ){
	    q_events['date_start'] = { "$gt": today.unix() }
	  }
	   
	   // Sort Dates
	  _opts['sort'] = {'date_start' : 1};
	  
	  
	  // Find Events
	  collectionAccess.collection('events').find(q_events, _opts, function (err, docs){
	    if(err){
	      response.body = err;
	      response.complete(400);
	    }
	   // logger("Length: " + docs.length);
	    
	    // Query
	    var q_evtUser = {};
	    if(docs.length !== 0){
	      q_evtUser["$or"] = [];
  	    for( var doc in docs){
  	      q_evtUser['$or'].push({
            "event._id" : docs[doc]._id.toString()
          });
  	    }
  	    q_evtUser["user._id"] = userID;
	    }
	    
	    
	    
	    collectionAccess.collection('eventuser').find(q_evtUser, {},  function(err, _docs){
	      if(err){
	        logger(err);
	        response.body = q_evtUser;
	        response.complete(400);
	      }
	      
	      var newDocs = [];
	      for( var doc in docs){
	        docs[doc].status = 0;
	        for( var doc2 in _docs){
	          if(docs[doc]._id == _docs[doc2].event._id){
	            docs[doc].status = _docs[doc2].status;
	          }
	        }
	      }
	      
	      
	      
	      //logger(docs);
	      logger("Length: " + docs.length);
	      response.body = docs;
	      response.complete(200);
	    });
	    
	  }); // collection
	  
	  
	})();

 My Script at the moment.

Any Ideas regarding this? :)

Best, Nico

Okay, i guess i solved it. ;)


Inside my preFetch Hook i do my stuff and end the function with response.complete(200);

Inside my app i have to detect - before the query - if the app is online or offline. Cause when it's offline, i need to null the query. (Cause the "contains hack" not working offline, of course. )

Thinking about manipulate the model, so that i don't need to handle the query 2 ways, but that's in future.

best, Nico

Login or Signup to post a comment