AngularJS: Setting Global Variable AJAX - 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)

Related

How to use the web api url across the mvc application

here is my piece of sample code
function AuthenticateLogin() {
$.getJSON('http://localhost:52293/api/APILogin/', function (data) {
if (data != null) {
}
}
);
}
The hosting url is below, which will be used across the mvc application, might be the controller/action will be varied across the application.
http://localhost:52293
for example, here i have hard coded the above url in all places, If I'm moving the application to other machine,then it is not good to change the url again in each and every places. so, is there any way to handle this ?
Give your API action a static name:
[RoutePrefix("api/APILogin")]
public class APILoginApiController {
[Route("", Name = "Login")]
public ActionResult Login(string userName) {
// ...
}
}
Then in your Razor JavaScript, you can utilize the UrlHelper by calling Url.HttpRouteUrl to dynamically build your URL for you.
$.getJSON('#Url.HttpRouteUrl("Login", new {})', function (data) {
// ...
});
The advantage of this approach is that if you change anything about how the route is formulated, it's in the [Route] attribute on the action. Matching the name like that will use the routing engine to always create the correct path. Otherwise, you're still stuck with (partial) hard-coded paths throughout your JavaScript.
If your route requires any variables, then that is provided within the empty anonymous object as the second parameter for HttpRouteUrl().
You should not hardcode the full absolute url like that. You may consider using the relative url. To generate relative url, you may consider using the Url helper methods
If your code is inside an external js file, you should consider using the helper method to generate the relative url in your razor view(s) and store it in a js variable which you can use in your external js files.
In your razor view
<script>
var myApp = myApp || {};
myApp.siteBaseUrl = "#Url.Content("~")"; // Get the app root
</script>
Now in your external js files
$.getJSON(myApp.siteBaseUrl+'api/APILogin/', function (data) {
// do something
});
You can also use Url.RouteUrl helper method to generate the urls to the api endpoints. For example
var myApp = myApp || {};
myApp.productsApiUrl = "#Url.RouteUrl("DefaultApi",
new { httproute = true, controller = "Products"})";
Now somewhere else in the js codde, you can use it like
$.getJSON(myApp.productsApiUrl , function (data) {
// do something with products data
});
This approach allows you to pass route values when you make the call and the helper method will build the url for you (based on the route definition)
myApp.productsDetailsUrl = "#Url.RouteUrl("DefaultApi",
new { httproute = true, controller = "Products", id= 210 })";

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

Backbone JS and CodeIgniter REST Server

I have a standard CI web app, but I've decided to get the chaotic javascript in order using backbone. I had a whole pile of serialized forms/jQuery AJAX requests to various controller methods: authenticate, change_password, register_member, request_new_password, etc.., and don't quite understand how REST works instead. I'm using Phil Sturgeon's REST library for CI https://github.com/philsturgeon/codeigniter-restserver
Should every backbone model have a different api url? And what am I supposed to actually call the controller methods?
<?php
require(APPPATH.'/libraries/REST_Controller.php');
class RestApi extends REST_Controller
{
function get()
{
But it just 404s.
I just don't get how to replace the routing to fifty of my old methods based on a handful of HTTP methods. Does the name of the backbone model need to match something on the server side?
You have to name your functions index_HTTPMETHOD. In your example it would be:
class RestApi extends REST_Controller {
// this will handle GET http://.../RestApi
function index_get() {
}
// additionally this will handle POST http://.../RestApi
function index_post() {
}
// and so forth
// if you want to POST to http://.../RestApi/somefunc
function somefunc_post() {
}
}
the url-attribute of the model should match the server-side 'url' which returns the JSON that will make up the model's attributes. Backbone.js has default functionality to this, which is to match the model's collection url with it's id attribute. The collection url requirement can be foregone by overriding the urlRoot -function, in order to operate model's outside of collections.
If you want to be independent of the id -attribute as well, you sould override the url -attribute/function to provide your own url that matches to the model on the server, like this:
url: 'path/to/my/model'
or
url: function() { // Define the url as a function of some model properties
var path = this.model_root + '/' + 'some_other_url_fragment/' + this.chosen_model_identifier;
return path;
}

Testing Ajax Request in Cakephp 2.0

I have an action in my controller which does something only if the request is an XmlHttpRequest, like this:
function myAction() {
if( $this->request->is('ajax') ) {
doSomething();
}
}
What would a TestCase for this action look like? Is there a way to mock up the CakeRequest instance to appear as an Ajax request?
I don't know if it is a good way or not, but adding
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
at the top of the test method will do the job. In this case we send data as Ajax so not need to check any more.
we use a trick to solve ajax unit test for cake2.0
as cake supoprts .json extention, we create a function in AppModel to cheat ajax call. like
public function isAjax() {
return $this->request->isAjax() || $this->request->ext == 'json';
}
Then in controller, instead of calling $this->request->isAjax(), $this->isAjax() is used.
When testing action with ajax call, we simply add suffix .json to the action call, For example,
$this->testAction('/users/register');
This might not be the ultimate solution for ajax call test, but could be a workaround

Resources