we are currently trying to get breeze and angular working together... one thing we are trying to avoid is having to manually call $scope.apply() after every remote procedure call... i am trying to write an "ajax" adapter instance that will use angular's $http service... the problem however is that angular's http service does not expose the xhr object... i think, not sure this is a problem because i believe breeze expects this object to be present, and even exposes it to the client... really the only thing i want to achieve is being able to call $scope.apply() AFTER breeze comes back from the server and does all of its work, including calling client callbacks... i would like to do this without making changes to the breeze source code, and i know breeze is very extensible... but it's also a very large library and i am having trouble pinpointing where the interception point is... does anyone have any advice??? thank you
You have correctly identified the issue. Right now Breeze does expect an XHR and angular does not return one. We have a feature request that should make it in one of the next few releases to allow you to wrap angular's http service as a 'breeze' ajax adapter.
For now though: (the rest of this is speculative and untested, but the general idea should work), your best bet might be to create a decorated version of the existing 'ajax' adapter. i.e. something like.
var origAjaxCtor = breeze.config.getAdapter("ajax");
var newAjaxCtor = function () {
this.name = "newAjax";
this._origAjaxCtor = new origAjaxCtor();
}
newAjaxCtor.prototype = new oldAjaxCtor(); // to delegate all other methods
newAjaxCtor.prototype.ajax = function (settings) {
settings.success = function((data, textStatus, XHR) {
// call the original success code
settings.success(data, textStatus, XHR);
// followed by your custom scope code.
// ...do your scope apply here...
});
// perform the actual ajax call - this will call your custom success method from above.
this._origAjaxCtor.ajax(settings);
}
// register the new adapter
breeze.config.registerAdapter("ajax", newAjaxCtor);
// make this adapter the default
breeze.config.initializeAdapterInstance("ajax", "newAjax", true);
As of Breeze 1.4.4, we now support an angular ajax adapter that uses $http. See the 1.4.4 release notes for more details.
For your specific issue, if you use the angular ajax adapter's setHttp method you can have Breeze use your $http instance internally.
Related
I need to provide a date format to our application. We use this to set the format for all display and input of dates.
I need to provide this in numerous places to the application. However, the date varies depending on the client. We have an API call that provides a variety of settings (one of which is the date config) as a JSON object.
I want to be able to provide an object representing the configuration options as a value via DI. There are lots of examples of providing values, but they are all static rather than dynamic.
I want to do something like this in my DI composition root
provide('DateFormat', {
useValue: 'dd/MM/yyyy'
})
However, I want 'dd/MM/yyyy' to come from settings at startup.
I have tried providing it via services, but it is causing issues with race conditions in a few places (value not available when one service runs). Some of this could be solved by re-writing it using more observables, but it just makes the code more complex. So I want some way to provide the object via DI and have the values set before doing anything else.
Any ideas how to achieve this?
If you provide the service in the bootstrap, or in the providers:[] in the root component of your app it will instantiate the service. In the service constructor you can get the data via the api.
If you need to wait until it loads before the first page shows, you could have one observable that indicates the data is loaded or not. Use that observable to route to a new component by subscribing to the observable. Or depending on the structure of your app, use *ngIf on the boolean observable set by the service to show an initialization screen until the api call returns and the data is initialized.
Any other component that needs that configuration can use that instance of the service by injecting via the constructor args.
import {ConfigurationService} from 'path/to/configuration-service';
#Component({
selector : '',
providers: [ConfigurationService] <<-- This instantiates a new
uninitialized service. Do this only in the root component.
})
export ComponentNeedingDateFormat() {
constructor(private configurationService: ConfigurationService) { }
}
If you include it in component providers: [] it will instantiate a new service. You want to inject it only in the root component.
https://angular.io/docs/ts/latest/guide/dependency-injection.html
First, the context of what I'm doing. I am running an HttpServer which is handling HttpRequests.
HttpServer.bind(ADDRESS, PORT).then((HttpServer server) {
listenSubscription = server.listen(onRequest);
});
void onRequest(HttpRequest request) {
//handle request here
}
I'd like to add some logging to all this, and due to the asynchronous nature of it all, want to add some identifying marker to the requests (so I can match up the request receipts with the responses, fer example). The code inside of onRequest() calls a bunch of other functions to do different things (handle GET vs POST requests, etc.), so simply generating an id at the top is a cumbersome solution as I'd have to pass it around through all those other function calls. I am, however, already passing around the HttpRequest object, so I thought it would be nice to throw an id field on it, just like you would in Javascript, except that Dart doesn't work that way.
Thoughts then went to subclassing the HttpRequest class, but converting the HttpRequest object the onRequest() method receives seemed like much more trouble and overhead than my needs required.
So I ask, is there any idiomatic Dart way attach some data to an existing object? If there isn't something idiomatic, what is the simplest (both in code and runtime complexity) way you can think of to accomplish this?
Well, there's an Expando, but I don't know the performance implications.
Something like:
// somewhere top level. Create this once.
final loggingId = new Expando();
...
// inside of onRequest
loggingId[request] = generateId();
...
// later inside log()
print(loggingId[request]);
Expandos are like weak-reference maps, from my understanding.
When I trace the code in zf2 , I can't find where the Application service registers.
Here is the code in application.php
public static function init($configuration = array())
{
$smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : array();
$serviceManager = new ServiceManager(new Service\ServiceManagerConfig($smConfig));
$serviceManager->setService('ApplicationConfig', $configuration);
$serviceManager->get('ModuleManager')->loadModules();
return $serviceManager->get('Application')->bootstrap();
}
The code "$serviceManager->get('Application')" is to get the Application service. But where did the application service register?
Then I find that the Application service is related with the code line "$this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULES_POST, $this, $this->getEvent())" in ZF2/library/Zend/MoudleManager/MoudleManager.php
public function loadModules()
{
if (true === $this->modulesAreLoaded) {
return $this;
}
$this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULES, $this, $this->getEvent());
/**
* Having a dedicated .post event abstracts the complexity of priorities from the user.
* Users can attach to the .post event and be sure that important
* things like config merging are complete without having to worry if
* they set a low enough priority.
*/
$this->getEventManager()->trigger(ModuleEvent::EVENT_LOAD_MODULES_POST, $this, $this->getEvent());
return $this;
}
The another question is that "ModuleEvent::EVENT_LOAD_MODULES_POST,That is loadModules.post.The first param of the trigger function is a function name. So is the loadModules.post a function ? where was it defined ?
Thanks in advance.
I'll address the last question first. The first param of the trigger method is not a function, it's simply a name; by convention, that name usually mirrors the method in which it is triggered, optionally with a suffix to give more context (such as ".pre", ".post", etc.).
"loadModules.post" is an event that is triggered by ModuleManager::loadModules() once all modules have been loaded. When an event is triggered, any listeners on that event will then be triggered with the parameters provided. The event object itself will also have a "target", which will be the ModuleManager in this case.
Regarding the "Application" service, you have to look into the internals of the MVC layer.
Most MVC services are defined in Zend\Mvc\Service\ServiceListenerFactory. If you look in that class, you'll see that it assigns Application to use the Zend\Mvc\Service\ApplicationFactory to create an Application instance. The ServiceListenerFactory is retrieved as part of the factory that creates the ModuleManager. It's a little indirect, but the relations are defined by the order of operations and the relations between the objects.
Most of the Zend\ServiceManager\ServiceManager registered service are configured by the ServiceListener factory Zend\Mvc\Service\ServiceListenerFactory when creating a ServiceListener instance.
The default config is actually stored in ServiceListenerFactory::defaultServiceConfig.
(If you go through the code you'll see that the 'Application' Alias is being defined there)
For you second question, the ModuleEvent::EVENT_LOAD_MODULES is just one of the ModuleEvent constants that are used to identify the different Modules loading events.
There are actually four module Events triggered at different stages by the application. I didn't have yet the opportunity to use those events, and I think that they're mostly used by the framework itself. So far, I had opportunities to use Zend\Mvc\MvcEvent related events only.
The question is how could I stop a method being called twice, where the first call has not "completed" because its handler is waiting for a url to load for example?
Here is the situation:
I have written a flash client which interfaces with a java server using a binary encrypted protocol (I would love to not have had to re-invent the whole client/server object communcation stack, but I had to encrypt the data in such a way that simple tools like tamper data and charles proxy could not pick them up if using SSL).
The API presents itself to flas as an actionscript swf file, and the API itself is a singleton.
the api exposes some simple methods, including:
login()
getBalance()
startGame()
endGame()
Each method will call my HttpCommunicator class.
HttpCommunicator.as (with error handling and stuff removed):
public class HttpCommunicator {
private var _externalHalder:function;
public function communicate(data:String, externalHandler:APIHandler):void {
// do encryption
// add message numbers etc to data.
this._externalHalder = externalHandler;
request.data = encrypt(addMessageNumers(data)));
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);
}
private function handleComplete(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
String data = decrypt(loader.data);
// check message numbers match etc.
_externalHandler(data);
}
The problem with this is I cant protect the same HttpCommunicator object from being called twice before the first has handled the complete event, unless:
I create a new HttpCommunicator object every single time I want to send a message. I also want to avoid creating a URLLoader each time, but this is not my code so will be more problematic to know how it behaves).
I can do something like syncronize on communicate. This would effectivly block, but this is better than currupting the data transmission. In theory, the Flash client should not call the same api function twice in a row, but I but it will happen.
I implement a queue of messages. However, this also needs syncronization around the push and pop methods, which I cant find how to do.
Will option 1. even work? If I have a singleton with a method say getBalance, and the getBalance method has:
// class is instantiated through a factory as a singleton
public class API{
var balanceCommunicator:HttpCommunicator = new HttpCommunicator(); // create one for all future calls.
public funciton getBalance(playerId:uint, hander:Fuction):Number {
balanceCommunicator.communicate(...); // this doesnt block
// do other stuff
}
Will the second call trounce the first calls communicator variable? i.e. will it behave as if its static, as there is onlyone copy of the API object?
If say there was a button on the GUI which had "update balance", and the user kept clicking on it, at the same time as say a URLLoader complete event hander being called which also cals the apis getBalance() function (i.e. flash being multithreaded).
Well, first off, with the exception of the networking APIs, Flash is not multithreaded. All ActionScript runs in the same one thread.
You could fairly easily create a semaphore-like system where each call to communicate passed in a "key" as well as the arguments you already specified. That "key" would just be a string that represented the type of call you're doing (getBalance, login, etc). The "key" would be a property in a generic object (Object or Dictionary) and would reference an array (it would have to be created if it didn't exist).
If the array was empty then the call would happen as normal. If not then the information about the call would be placed into an object and pushed into the array. Your complete handler would then have to just check, after it finished a call, if there were more requests in the queue and if so dequeue one of them and run that request.
One thing about this system would be that it would still allow different types of requests to happen in parallel - but you would have to have a new URLLoader per request (which is perfectly reasonable as long as you clean it up after each request is done).
im calling an actionscript class from my main mxml file. the actionscript class is responsible for calling a web service and handling the response, however im having trouble and keep getting the following error; (im new to flex btw)
Error #1009: Cannot access a property or method of a null object reference.
my code goes as follows;
public function getSites(argWsdl:String):void{
ws = new WebService();
ws.loadWSDL(argWsdl);
ws.getSites.addEventListener(ResultEvent.RESULT,echoResultHandler);
ws.getSites();
}
public function echoResultHandler(event:ResultEvent):void {
var siteField:ArrayCollection = event.result as ArrayCollection;
Application.application.setSiteField(siteField);
}
when i run the debugger the code never reaches the result hanlder and i see the #1009 error in the variable list.
any ideas?
looks like you have it sorted, but just to add more information in case someone else comes along to this question, you generally see this error when you are trying to use something that hasn't been created yet. A lot of the time you will see it when trying to access UI components that have not yet been created (its good to rely on the creationComplete event for these sort of things), but in this case it looks like you are using the webservice before it is completely ready (the wsdl hasnt been loaded yet).
Just so you know, you can also define your webservices in mxml (mx:webservice) and specify the wsdl there or you can also load the wsdl later on from a configuration file afterwards just by referencing the ID.
sorted it out,
i needed to created a loadEvent and loadhandler. Once loadWsdl is called the loadhandler specifies the laodHandler to use, inside the loadHandler i call the method name as seen in the wsdl
thanks Ryan,
the main reason im using a seperate actionscript class is so i can reuse the same web service calls across my components without having to retype the same code. I couldnt think of a better way to do this - maybe a could have done the same with a custom component