How to update cache for a Sitecore Web Api output upon the index update - sitecore

I am implementing Sitecore 8 Web Api. To be exact, i am using ServiceApiController in Sitecore Services Infrastructre. I wonder how can I cache the JSON output from this controller in such a way that it gets updated only if the lucene index which I am fetching data from, gets rebuilt?
I have not registered this controller as controller rendering because apparently we don't need to do that and it just works out-of-box. I just read the JSON output by an ajax call through jQuery and the javascript code and HTML markup is inside a MVC view rendering. I guess it doesn't make sense to setup cache on the view rendering. Isn't it?
What should i do?

The best option would be to use the HtmlCache and store the data there. This cache gets completed cleared on a publish, so it would make sense to use it.
You can add an entry into the cache by using the SetHtml method:
var cache = Sitecore.Caching.CacheManager.GetHtmlCache(Sitecore.Context.Site);
var json = cache.GetHtml("mycachekey");
if (string.IsNullOrWhiteSpace(json))
{
var json = // build your json output here
cache.SetHtml("mycachekey", jsonValue);
}
return json;

Related

How to unload a record in Ember 2.3.0?

I am upgrading an Ember 1.13.0 application to Ember 2.3.0 and I'm facing a little issue where I am unable to unload a record from the Data Store without causing Ember to make a HTTP request. I do not want to delete the record in the server. I simply want to remove it from Ember Data Store.
I was using the following Ember DS.Store API: http://emberjs.com/api/data/classes/DS.Store.html#method_unloadRecord in Ember 1.13.0 and it worked fine. Sample:
this.store.find('post', 1).then(function(post) {
this.store.unloadRecord(post);
});
After upgrading to 2.3.0, when I monitor the network tab in Chrome, Ember is making a GET request to find the record and then unload it. Because it fails to find (our server does not have an API to match this call), it doesn't unload the record and the changes don't appear in the UI.
I tried to fix this by instead doing something like:
this.store.peekRecord('posts', 1).then(function(post) {
this.store.unloadRecord(post);
});
but this doesn't seem to work. What is the right way to unload a record from Ember Data without making HTTP calls? Thanks.
Ember data automatically reloads records to keep them in sync with server. So findRecord() resolves immediately, but in background it makes request to the server and update values when it returns. This behavior was changed in ember-data 1.13.0 and is described in toc_new-adapter-hooks-for-better-caching.
The issue with peekRecord is that peek* methods just asks store and thus don't need to return promise. Therefore your code should look like this:
const store = this.get('store');
const post = store.peekRecord('posts', 1);
if (post) {
store.unloadRecord(post);
}

EmberJs: Update the Data Store Schema

I'm currently developing an Ember application and I've come across a blocker...
I am loading my data from a RESTful api and this was working a treat, but I have now updated one of my models with 2 new fields. The server is returning the new json format and it includes the new field. DS.Model consumed by the ember application also contains the new fields but when I view the Data in the chrome plugin, the schema does not seem to reflect the changes to the model. I have tried clearing the cache in the browser but it does not seem to force the schema to update.
Any pointers?
Ok I have done a bit more digging and it seems to be an issue with the Chrome plugin
The datagrid view does not display the new columns but if you drill into the rows then the attributes ARE being shown, this has at least pointed me in the correct direction.

How do I access the URL that Ember Data will PUT to?

I'm adapting an old JS (no framework) + Rails app as an Ember learning exercise. The idea of the application is that I'm producing a pdf from some data input. In the initial version, there was no user persistence - you could modify the data provided to you in the tables, and then download the PDF of it.
As part of this, I decided to run with a decidedly non-standard ember framework - I'm essentially using Ember Data to load the initial value of the tables. Ember has been a really natural fit for the models I have on the Rails side, and it's made a lot of the more complicated calculations a lot easier. The issue I have is that my initial idea was that when I came to download the PDF, I'd respond to the "save" action on Ember Data with binary data (with an application/pdf header), which I could then use something like FileSaver.js to serve up to the client. Then, I found that EmberData needs JSON return value.
So I base64 encoded my PDF response and fired it back..but it didn't fit the model schema. I thought I'd then do a manual AJAX save -
CalculateYourTV.RostersShowController = Ember.ObjectController.extend({
actions:{
download: function(){
var roster = this.get("model");
var team = roster.get('team');
return this.ajax('*URL GOES HERE*', record.toJSON(), "PUT").then(function(data) {
console.log('called')
console.log(data)
});
},
}
})
And this is where I'm currently stuck. Is there any way to access the URL that EmberData is posting to? I could hard-code a route in the Rails side of things, but I don't like hardcoding routes in here, and I'd like to keep it as reusable as possible (I'm planning to eventually allow data persistance).
Just open chrome dev tools (or firebug) and monitor what's going on in the network tab. You should see any ajax request your application sends out, including the EmberData's save request.
You can change the URL that a specific model will hit by creating custom Ember Data adapters per model.
For example, say you have a person model that needs to not hit the default /persons URL.
App.PersonAdapter = App.ApplicationAdapter.extend({
pathForType: 'special/custom/endpoint/for/folks'
});
That said, Ember Data may not be the best tool here for your PDF "model". You can always use Ember Data for the majority of your models, but use a quick $.ajax for other stuff that doesn't fit your definition of a true model.
You can ask the adapter to build a URL for you -
adapter = #store.adapterFor('application')
url = adapter.buildURL(type, id)
where type is the name of the model, and id is its id.
If want to look up the adapter directly in the container it is
#container.lookup('adapter:application')

How django and ExtJS passing data to each other by JSON?

I am new to web development, recenlty I am learning to build a webserver using django + ExtJs. but I am confusing about how to use django + ExtJS together.
For django, it has template to display the data, the parameter passing to html files could be dict, and could send JSON. I am trying to use it as the backend of the webserver.
ExtJS, support JSON.
Then here comes myquestion:
How to make .html files( used by django as the template layer) to accept "JSON"? It seems that ExtJS has no ability of sending json data through socket or other IPC.
It seems that ExtJS has the ability to use AJAX to "post" the data to backend, however, I am not sure how the .html could get data from backend using JSON? I downloaded ExtJS the 4.2.1 version, and find some examples in the files, however, it only give some example to get data from "json files".
Can someone give me an example or show me which aspect I should learn or explain its mechanism briefly?
This is done not at template layer, but at view level. You should write a view function in Python and assign it to some URL address. In that view function, you can access JSON data sent by ExtJS and process it how you wish.
I totally misread your question, here's the updated answer:
On Django side, you should write a view function, which would return JSON response, and assign that view to some URL address. (See How to write a view in Django documentation, if you're new to this.)
On ExtJS side, you should make an Ajax request to that URL, and provide success callback function that will be able to access the output of Django view function. (Seems like Ajax requests in ExtJS are usually done using Ext.Ajax.request.)

Applying Javascript MVC architecture on existing backend MVC

We currently have a large implementation done in Django which mostly spit out static HTML. We are planning to implement a javascript modular framework to hook to django's API and define needed routes..etc
But, we do not want to scratch off what we did so far as the site is completely functional for non-js users. The more I read about JavaScript MVC designs, the more I find it impossible to implement the two to work together.
Any ideas of how to proceed in that direction? is there a best practice that someone can follow?
Keep what you got right now as a fail-safe. Create new, separate views meant for Ajax requests that handle the processing of data and respond with appropriately formatted respond data (XML, JSON etc.).
Basically, Django is your model. Any action defined by your Javascript controller can either modify the model or the view.
If it modifies the view, there are two options: you either change just the display of data, and thus you just call a Javascript function that alters the HTML, or you display new data. In that case, you have to create a Django view that supplies that data in a format that Javascript can process easily. In your Ajax request, supply a callback (the view part of your Javascript) that handles displaying that data.
If the action modifies the model, you also need to create a Django view that processes the POST data sent by the Ajax request as needed, and returns either the error messages or a success message in a format that is, again, easily processed by Javascript. Again, you should register a callback to your Ajax request that handles the display of the messages returned by Django.
So basically, the only change to your current views would be that you supply the appropriate Javascript code to map the actions to Ajax requests and to handle the data returned by Django for your Ajax requests. Everything else should be done in separate Django views.