Unable to consume an Angular service from a Controller - ajax

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

Related

AJAX how to return a value

I know this is a question that's been asked to death, but I still struggle with how to use callbacks. I just want to return a value from the ajax's request.done outcome. I tried to follow Felix Kling's very informative answer on using callbacks with AJAX, but can't get my code to work.
My code below submits a form with user input data to the database. I would like it to retrieve the property employeeId. I am able to alert the correct value inside the submit function, but I would like to use this value in other functions. From reading up on asynchronous functions,i think this is because submit function exits before returning the value. I would really appreciate some guidance on using callbacks to return values.
I tried to only include the code pertaining to my issue
$('#employeeForm').submit(function(event,callback){
var values = $(this).serialize(); //gather form data
var result = foo(); //callback implementation from Felix Kling's SO answer
foo(function(result){
var request = $.ajax({
url: "game.php",
type:"post",
dataType:"json",
data: values
});
function foo(response.employeeId){ //I am trying to return value response.employeeIda in the success situation
request.done(function (response,textStatus,jqXHR){
document.getElementById("submitEmployeeInfo").innerHTML=response.employeeId;
var employeeId = response.employeeId;
}
});
})

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);
}
}
}
});

AngularJS: Setting Global Variable AJAX

I am looking for best practices with AngularJS:
I need to share a json ajax response between nested controllers.
Controller1->Controller2->Controller3
Right now I have a working version that simply sets a $scope.variable with the response in controller1, and the other controllers access it by calling the same variable.
I have tried creating a global service, but the problem is I make the ajax call in a controller, and before the ajax call is finished, the global variable defaults to null for all the other controllers.
I am just trying to understand what best approach is in this situation.
Thanks
Create publisher/subscriber service or factory and subscribe methods from your controller2 and 3 to data change. Just like this:
angular
.module('')
.factory('GlobalAjaxVariable', function() {
var subscribers = [];
function publish(data) {
callbacks.forEach(function(clb) {
clb(data);
});
}
return {
setData: function(ajaxData) {
publish(ajaxData);
},
addSubscriber: function(clb) {
subscribers.push(clb);
}
};
});
You can put the value in $rootScope.variable and after access it from any other controller (as $scope.variable)

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

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
});

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...
}
});

Resources