Ember model hook in Route vs Ember.Object.extend({}) - ajax

What's the difference between using the model hook in an Ember Route:
App.PhotoRoute = Ember.Route.extend({
model: function(params) {
return Ember.$.getJSON('/photos/'+params.photo_id);
}
});
Versus creating your own Ember Object?
App.PhotoModel = Ember.Object.extend({});
App.PhotoModel.reopenClass({
find: function(id){
$.ajax({
url: 'https://www.go.get.my.photo',
dataType: 'jsonp',
data: { id: id },
success: function(response){
return response.data;
}
});
}
});
Why would you use one over the other?

One is part of the workflow and the other is a class.
The model hook will provide the model for a route when it's accessed (in that case photo). Additionally it will wait for the async call to complete and use the result of the ajax call.
Example: http://emberjs.jsbin.com/
Extending Ember.Object will define a class for reusability. It's very much a building block for the entire Ember framework.
App.MyModelObject = Ember.Object.extend({});
A more useful example would be
App.MyModel = Ember.Object.extend({
total: function(){
return this.get('val1') + this.get('val2');
}.property('val1', 'val2')
});
var foo = App.MyModel.create({val1:3, val2:5});
console.log(foo.get('total'));
Example: http://emberjs.jsbin.com/xinozi/1/edit

The two are completely different. model on an Ember route is a hook which ember gives you to (fetch data from an api and create an object that holds the data your controller needs and so on) return a promise which gets resolved to the route's controller's model, when the said route is entered and transitioned into. On the other hand, App.MyModel = Em.Object.extend({}) creates a class which is just a template from which objects which are instances of App.MyModel can be instantiated.
If your application wanted to model users, for example, it would have a user "model" like
App.User = Em.Object.extend({username: 'Alice'})
or something similar. However, if you have a user route which looks like /#/user/id, then the model hook on the route would be something like this
model: function(params) {
return new Ember.RSVP.Promise(function(success, failure) {
//make an ajax call and invoke the success and failure handles here appropriately
});

Related

Update Ember model live via action

I'm new to Ember.js and keep struggling on a simple task. My goal is to achieve live update of the page content after action is triggered. I'm quite lost in Ember logics regarding route-controller-model relationship in this case.
So my template.hbs is something like:
<h1>{{model.somedata}}</h1>
<button {{action 'getContent'}}>Get Content</button>
My controller accepts some params from user form and makes the AJAX call:
export default Ember.Controller.extend({
somedata: 'hello',
actions: {
getContent: function () {
var self = this;
Ember.$.ajax({
// ... standart call with some query data
success: function(result) {
self.set('somedata', result);
}
});
}
}
});
My route model returns only controller params, so if I get it right as controller properties get updated, there must be a simple step to update the current model and display all changes to the template.
export default Ember.Route.extend({
model: function(params) {
return params;
}
});
Can you guys give me a tip how this process is regularly built in Ember?
You are looking for self.set('model.somedata', results).
Your code as it stands is setting the somedata property on the controller, which doesn't affect anything.
Yeah it's a bit confusing, here's how I think of it...
First Ember sets up the route.
The route has multiple hooks that are used to get and process the model (i.e. beforeModel, model, afterModel). Ember will always look for these as part of it's opinionated nature.
There is also a setupController hook that will fire after all the model hooks. As part of the setupController hook, the controller will be created and the model will be passed to the controller.
Once that happens, I've found it helpful to think of the model as no longer being part of the route, but the controller instead.
Controllers will be deprecated. So IMO do not use controllers.
Handle that action in your route. If you bind value to the object returned by model hook, your data and page will be updated when you update the value.
export default Ember.Route.extend({
somedata: null,
model: function(params) {
return {
params: params,
somedata: this.get('somedata')
};
},
actions: {
getContent: function () {
...
var _this = this;
...
success: function(result) {
_this.set('somedata', result);
}
}
}
});

Unable to consume an Angular service from a Controller

So I've done extensive research and read many tutorials but I can't find a straightforward answer to what I'm trying to accomplish.
I'm simply trying to access a JSON object stored at JSON-Generator.com and stick it in a table and repeat it. Sounds simple enough but it seems there many different ways to do this and all the sources leave out the one piece of info I need.
if I console.log eventsService inside the controller it returns a constructor, if I console.log eventsService.data it returns undefined.
How do I access the data returned from $http in my controller?
// CONTROLLERS
app.controller('currentTradeshowsController', ['$scope', 'eventsService', function($scope, eventsService){
$scope.events = eventsService.data;
}]);
// SERVICES
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
$http({method: 'GET', url: eventsUrl}).
success(function(data){
// not sure what to write here....
return data;
})
.error(function(){
console.log('ah shit');
})
});
first of all, $http call is asynchronous, so you probably want to use promises to load the data correctly into scope variable
second - you need to return something from the service to make it work outside of the service declaration function
controller
app.controller('currentTradeshowsController', function($scope, eventsService){
eventsService.getData().then(function(data) {
$scope.events = data;
});
});
service
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
return {
getData: function() {
return $http.get(eventsUrl);
}
}
});
$http.get is a shorthand for GET request, and it returns a promise, so you can simply use it with .then in the controller

How do I cause an MVC controller to redirect the user from an ajax call?

I am sending an array as the "data" value (parameters) of an ajax call to an MVC controller. The controller should then redirect the user to a new page but it does not. Instead I can see in the Preview window that the View is being returned but through the ajax return. I am not sure if the way I am approaching this is correct because I seem to be having a hard time finding good examples to follow. I wanted to avoid an Html.ActionLink because I will have about 20 parameters to pass to the controller.
Here is the function that sends the array to the controller:
submit: function () {
var data = {
"ReqDepartment": (viewModel.reqDepartment === null) ? null : viewModel.reqDepartment,
"EquipmentGroup": (viewModel.equipmentGroup === null) ? null : viewModel.equipmentGroup,
"SiteCode": (viewModel.site === null) ? null : viewModel.site.SiteCode,
}; //header
$.ajax({
type: "POST",
url: "/ArctecLogisticsWebApp/Requisitions/ReqsSummary/",
data: data,
traditional: true
});
}
Here is the controller, ReqSearchCriteria is a ViewModel :
public ViewResult ReqsSummary(ReqSearchCriteria criteria)
{
return View("ReqsSummary", requisitionsRepository.GetReqsAdvancedSearch(criteria));
}
The controller is returning the View in the ajax call. Should I use a different approach to send an array to the controller?
ajax calls won't redirect by themselves. what you need to do is return json from the controller to the view with the result of the action and if the action is successful then redirect
$.ajax({
type: "POST",
url: "/ArctecLogisticsWebApp/Requisitions/ReqsSummary/",
data: data,
traditional: true,
success: function(result){
if(result.Success){
window.location = '#Url.Action('Action', 'Contorller')';
}
}
});
Edit:
The controller method you have will work. It should be a different name from the form you are redirecting from to eliminate confusion. Through data you can pass any information that you need.
data: { id: $('.id').val() },
something like this will pass whatever value is in the field with class id. then on your controller create the model for the view and return view. I use ajax calls everywhere, they are incredibly useful. Please let me know if you have any other questions.
You don't have to check for a result in your success/done handler and then do the redirect manually. You can actually return a JavascriptResult from your controller and it will redirect for you:
$.ajax({
type: 'post',
url: '/Home/DoStuff'
});
[HttpPost]
public ActionResult DoStuff()
{
return JavaScript(string.Format("window.location='{0}';", Url.Action("About")));
}
If you wanted to get fancy you could even create a new ActionResult type that took care of the formatting for you. Or you could detect if it is an AjaxRequest and determine if you should do a RedirectToAction or a JavaScript result.

Ajax call return json to model I can use data from in my own function

New to Backbone, so I may be over/under complicating things. (built spa's with my own functions in the past)
Psudo code of what I used to do:
AjaxCall(
url: "get json result"
success:
parse json
call Update(json.a, json.b)
)
function Update(a, b){
//do something with a/b var's
}
For a more abstract idea of what I am envisioning atm. If I click an update button, I want it to hit the server and return a success/fail status along with an Id and a message (imagining all in json format).
Found a few examples, but none seem to fit so far.
To do that, you'd use a Backbone model:
var Message = Backbone.Model.extend({
urlRoot: "messages"
});
var myMessage = new Message();
myMessage.save({}, {
success: function(model, response, options){
// code...
},
error: function(model, xhr, options){
// code...
}
});
Basically: the model configures the API call, and save will use backbone's sync layer to handle the actual AJAX. You can pass success and error callbacks to the `save function.
The first parameter to the save function are the attributes which are to be saved (see http://backbonejs.org/#Model-save), which seem to need to be empty according to your question.
Since the model instance has no id attribute, the save call will trigger a POST request to the API. If by any chance you actually need to provide an id (so that a PUT call gets triggered instead), simply do
myMessage.save({id: 15}, {
success: function(model, response, options){
// code...
},
error: function(model, xhr, options){
// code...
}
});

What Goes in the Controller for an AJAX get request in GRAILS

I have an AJAX call in my view,
var ajaxData= $.ajax({
type: "GET",
url: "${createLink(controller:'profile',action:'ajaxList')}",
success: function(data) {
}
});
I created a method in the ProfileController.groovy class in order to return "data" from this call, but I don' know how to format the controller correctly. Here is what I want to return. The model, profile, has a name and a description. I want to return a hash object where the key is the name and the value is the description. Is there a way to do this in the controller so that this ajax call returns that hash. Any help would be aprpeciated. Thanks!
In your controller's ajaxList action build your model as you want it, as usual, and then instead of return model at the end you want to render model as JSON.
For example,
class ProfileController {
def ajaxList() {
def profiles = Profile.list()
def model = profiles.collect { [(it.name): it.description] }
render model as JSON
}
}
And if you want to use the same list action for returning different formats, look at using withFormat.

Resources