Can I assign a Future to a controller's attribute in AngularDart? - dart

I need to get a list of values asynchronously from the server. The API's method returns a Future.
Of course I can create a callback and assign the result manually, I wonder if there's a way to delegate this to AngularDart?
class IndexPageController {
var apps;
EasyAPIClient api = new EasyAPIClient('/api/');
IndexPageController() {
_loadData();
}
_loadData() {
api.getAppNames().then((app_names){
apps = app_names;
});
}
}
What I'd like to have approximately:
class IndexPageController {
var apps;
EasyAPIClient api = new EasyAPIClient('/api/');
IndexPageController() {
_loadData();
}
_loadData() {
// this code executes successfully,
// however the template never receives the list.
apps = api.getAppNames();
}
}

AngularDart doesn't currently support Futures/Streams in templates.

Related

breeze.js navigation properties not available to custom initializer when importing

When retrieving entities and metadata from the server my custom initializer functions are able to access thier navigation properties as expected. When exporting metadata and entities to localstorage and reimporting them the navigation properties are not available. I have ensured that the ctors and initializers are registered to the metadatastore before import as the methods are called. I took a look at the breeze source and it appears that the initialize functions are called prior to the item being fully populated and attached.
targetEntity = entityType._createEntityCore();
updateTargetFromRaw(targetEntity, rawEntity, dataProps, true);
if (newTempKeyValue !== undefined) {
// fixup pk
targetEntity.setProperty(entityType.keyProperties[0].name, newTempKeyValue);
// fixup foreign keys
if (newAspect.tempNavPropNames) {
newAspect.tempNavPropNames.forEach(function (npName) {
var np = entityType.getNavigationProperty(npName);
var fkPropName = np.relatedDataProperties[0].name;
var oldFkValue = targetEntity.getProperty(fkPropName);
var fk = new EntityKey(np.entityType, [oldFkValue]);
var newFkValue = tempKeyMap[fk.toString()];
targetEntity.setProperty(fkPropName, newFkValue);
});
}
}
*targetEntity.entityAspect._postInitialize();*
targetEntity = entityGroup.attachEntity(targetEntity, entityState);
if (entityChanged) {
entityChanged.publish({ entityAction: EntityAction.AttachOnImport, entity: targetEntity });
if (!entityState.isUnchanged()) {
entityGroup.entityManager._notifyStateChange(targetEntity, true);
}
}
}
if (targetEntity) {
targetEntity.entityAspect.entityState = entityState;
if (entityState.isModified()) {
targetEntity.entityAspect.originalValuesMap = newAspect.originalValues;
}
entityGroup.entityManager._linkRelatedEntities( targetEntity);
}
If I move the post initialize call below the ._linkRelatedEntities call it appears to work exactly as the query materialization
if (targetEntity) {
targetEntity.entityAspect.entityState = entityState;
if (entityState.isModified()) {
targetEntity.entityAspect.originalValuesMap = newAspect.originalValues;
}
entityGroup.entityManager._linkRelatedEntities( targetEntity);
*targetEntity.entityAspect._postInitialize();*
}
Am I missing something here? Is this the designed functionality? I have found a work around by passing in the EntityManager, setting the entityAspect manager and calling loadNavigationProperties however this seems redundant. Any insight fromt he Breeze folks would be greatly appreciated.
Thanks,
Brad
Not sure but this issue might be related to a bug that we just fixed in Breeze 1.4.1 available now.

Log any action made by users in sfDoctrineGuard

I need to log any action made by users in sfDoctrineGuard plugin. Basically I'll need to log:
module/action
date
IP from where users are accessing the application
Any plugin? Is that possible? How?
This could be probably the plugin you need, sfDoctrineGuardLoginHistoryPlugin and allows to extend the information that you save.
Check for more plugins here.
Take a look at the code of the plugin, you just need to change the following file: PluginUserLoginHistoryTable.class.php
Add in the function writeLoginHistory and createHistoryEntry the information you want:
writeLoginHistory(sfEvent $event) {
//... same code than in the plugin
//lets save module and action
if (!isset($request) )
{
$sActionName = sfContext::getInstance()->getActionName();
$sModuleName = sfContext::getInstance()->getModuleName();
}
else
{
if (isset($request["module"]))
{
$sActionName = $request["action"];
$sModuleName = $request["module"];
}
}
//get values from the http bar URL
if (!isset($sModuleName))
{
$sFullURL = sfContext::getInstance()->getRouting()->getCurrentInternalUri();
///... strip action and module name from the above URL
}
}
Remember to pass those values to createHistoryEntry function and also to update that function with more input values to be saved.

indexed_db getObject() - how to return result

I would like to know how to define the data type and how to return the object (record) using getObject(). Currently, the only way that I have been able to use the result (record) outside of the function that obtains it is to call another function with the result. That way, the data-type does not need to be specified. However if I want to return the value, I need to define the data-type and I can't find what it is. I tried "dynamic" but that didn't appear to work. For example ":
fDbSelectOneClient(String sKey, Function fSuccess, String sErmes) {
try {
idb.Transaction oDbTxn = ogDb1.transaction(sgTblClient, 'readwrite');
idb.ObjectStore oDbTable = oDbTxn.objectStore(sgTblClient);
idb.Request oDbReqGet = oDbTable.getObject(sKey);
oDbReqGet.onSuccess.listen((val){
if (oDbReqGet.result == null) {
window.alert("Record $sKey was not found - $sErmes");
} else {
///////return oDbReqGet.result; /// THIS IS WHAT i WANT TO DO
fSuccess(oDbReqGet.result); /// THIS IS WHAT i'm HAVING TO DO
}});
oDbReqGet.onError.first.then((e){window.alert(
"Error reading single Client. Key = $sKey. Error = ${e}");});
} catch (oError) {
window.alert("Error attempting to read record for Client $sKey.
Error = ${oError}");
}
}
fAfterAddOrUpdateClient(oDbRec) {
/// this is one of the functions used as "fSuccess above
As someone else once said (can't remember who), once you start using an async API, everything needs to be async.
A typical "Dart" pattern to do this would be to use a Future + Completer pair (although there's nothing inherently wrong with what you've done in your question above - it's more a question of style...).
Conceptually, the fDbSelectOneClient function creates a completer object, and the function returns the completer.future. Then, when the async call completes, you call completer.complete, passing the value in.
A user of the function would call fDbSelectOneClient(...).then((result) => print(result)); to make use of the result in an async way
Your code above could be refactored as follows:
import 'dart:async'; // required for Completer
Future fDbSelectOneClient(String sKey) {
var completer = new Completer();
try {
idb.Transaction oDbTxn = ogDb1.transaction(sgTblClient, 'readwrite');
idb.ObjectStore oDbTable = oDbTxn.objectStore(sgTblClient);
idb.Request oDbReqGet = oDbTable.getObject(sKey);
oDbReqGet.onSuccess.listen((val) => completer.complete(oDbReqGet.result));
oDbReqGet.onError.first.then((err) => completer.completeError(err));
}
catch (oError) {
completer.completeError(oError);
}
return completer.future; // return the future
}
// calling code elsewhere
foo() {
var key = "Mr Blue";
fDbSelectOneClient(key)
.then((result) {
// do something with result (note, may be null)
})
..catchError((err) { // note method chaining ..
// do something with error
};
}
This future/completer pair only works for one shot (ie, if the onSuccess.listen is called multiple times, then the second time you will get a "Future already completed" error. (I've made an assumption on the basis of the function name fDbSelectOneClient that you are only expecting to select a single record.
To return a value from a single future multiple times, you'll probably have to use the new streams feature of the Future - see here for more details: http://news.dartlang.org/2012/11/introducing-new-streams-api.html
Note also, that Futures and Completers support generics, so you can strongly type the return type as follows:
// strongly typed future
Future<SomeReturnType> fDbSelectOneClient(String sKey) {
var completer = new Completer<SomeReturnType>();
completer.complete(new SomeReturnType());
}
foo() {
// strongly typed result
fDbSelectOneClient("Mr Blue").then((SomeReturnType result) => print(result));
}

Calling background method from mvc4 view

I want to call method which will do something in background, but I don't want to change the current view. This is the method:
public ActionResult BayesTraining(string s,string path)
{
XmlParse xp = new XmlParse();
using (StreamWriter sw = System.IO.File.AppendText(path))
{
sw.WriteLine("d:/xml/"+xp.stripS(s)+".xml");
sw.Close();
}
return RedirectToAction("Index");
}
As you can see, I'm currently using RedirectToAction, that just reloads the page after the method is done working. Having in mind that method doesn't effect UI, I don't want to refresh web page every time I've used it. It's job should be done in background. So, how could I call it, without the need to redirect the view?
If you want something you can fire and forget use an ajax call. For instance if you change your action method to
public JsonResult BayesTraining(string s,string path)
{
XmlParse xp = new XmlParse();
using (StreamWriter sw = System.IO.File.AppendText(path))
{
sw.WriteLine("d:/xml/"+xp.stripS(s)+".xml");
sw.Close();
}
return Json("Success");
}
Then in your view bind to the UI event you need to via jQuery, for instance to bind to a button with id of BayesTraining do the following
$("#BayesTraining").click(function(){
$.post('#Url.Action( "BayesTraining" , "ControllerNameHere" , new { s = "stringcontent", path="//thepath//tothe//xmlfile//here//} )', function(data) {
//swallow success here.
});
}
DISCLAIMER: above code is not tested.
Hopefully it'll point you in the right direction.
If the method doesn't affect the UI, does it need to return an ActionResult? Couldn't it return void instead?
public void BayesTraining(string s,string path)
{
XmlParse xp = new XmlParse();
using (StreamWriter sw = System.IO.File.AppendText(path))
{
sw.WriteLine("d:/xml/"+xp.stripS(s)+".xml");
sw.Close();
}
}

Create a web part which takes input from a tasklist

I'm in need of creation of a web part which takes input from a task list and changes the color of the tasklist based on the data in the task list. Can anyone help me with this problem?
I can write code in visual studio 2005.
My question is how do I take input data from the list?
Sample code here. This should get you started. (source)
using Microsoft.SharePoint;
class SPTest {
public void ReadList() {
// Use using to make sure resources are released properly
using(SPSite oSite = new SPSite(pathToSite)) {
using(SPWeb oWeb = oSite.AllWebs[nameOfWeb]) {
// Alternately you can use oSite.RootWeb if you want to access the main site
SPList oList = oWeb.Lists[listName]; // The display name, ie. "Calendar"
foreach(SPListItem oItem in oList.Items) {
// Access each item in the list...
DateTime startTime = (DateTime)oItem["Start Time"];
// etc....
}
}
}
}
}

Resources