How to dynamically change eventHandler in Famo.us/Angular fa-pipe-to - famo.us

I'm trying to modify eventHandler on fa-pipe-to in my controler but modification is not working.
In my view, i have a 'scroll-view' with a surfaces loop.
Each surface pipe a event handler.
<fa-scroll-view fa-pipe-from="scrollEventHandler">
<fa-view ng-repeat="tile in tiles">
<fa-modifier fa-transform="tile.transform">
<fa-container-surface fa-pipe-to="tile.eventHandler">
<fa-modifier fa-opacity="tile.opacity">
<fa-surface fa-background-color="tile.color"/>
</fa-modifier>
</fa-container-surface>
</fa-modifier>
</fa-view>
</fa-scroll-view>
In my controller, I have an object with 2 eventHandlers :
function Object() {
this.eventHandler = null;
$scope.scrollEventHandler = new EventHandler();
var dragEventHandler = new GenericSync();
var activateDragMode = function() {
this.eventHandler = dragEventHandler;
}
}
By default I use scrollEventHandler and it works :
this.eventHandler = $scope.scrollEventHandler;
But during execution i want to switch to other eventHandler :
activateDragMode();
So my problem is : when i set new eventHandler to 'eventHandler' variable, eventHandler is not updated.
Does anyone has a solution to do it?

OK, i found my error :
When i was debugging 'activateDragMode()' function, i could see that 'this.eventHandler' was undefined, and 'this' was not my Object but was EventHandler.
So, i added .bind(this) to my function to bind the content of my object and everyting was working good :
var activateDragMode = function() {
this.eventHandler = dragEventHandler;
}.bind(this);

Related

recycler adapter is not updating on calling notifydatasetchanged()

I passed a list to the adapter from an activity and on calling notifydatasetchanged, recycler view is still empty, It is not updating the view.
var list : ArrayList<StationBean> = ArrayList()
override fun getItemCount(): Int {
return list.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.stations_adapter, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.stationsName.text = list.get(position).stationName
holder.cityName.text = list.get(position).latitude.toString()
}
fun add_data(data : StationsListDataClass)
{
list = data.stationBeanList
notifyDataSetChanged()
Log.d("List", list.toString())
}
}
////// . Setting the adapter .
private var adapter: StationsListAdapter = StationsListAdapter(this)
recycler_view_stationsList.apply {
layoutManager = LinearLayoutManager(this.context)
this.adapter = adapter
}
///// Layout File
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_stationsList"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
/>
// . Main Activity Full Code , I used inject for calling presenter,The main problem is in the setRecycler function
#Inject
lateinit var stationsListPresenter: StationsListPresenter
private lateinit var station_adapter: StationsListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_stations_list)
setupRecycler()
stationsListPresenter.downLoadStationsListUsingRetrofit()
}
private fun setupRecycler()
{
val recyclerView : RecyclerView = findViewById(R.id.recycler_view_stations_list)
recyclerView.apply {
layoutManager = LinearLayoutManager(this#StationsListActivity) // replace MainActivity with your activity name
station_adapter = StationsListAdapter(this#StationsListActivity)
}
recyclerView.adapter = station_adapter
}
override fun addNewsToRecyclerView(stationsList: StationsListDataClass)
{
station_adapter.add_data(stationsList)
}
override fun makeInjection(activityComponent: ActivityComponent) {
activityComponent.inject(this)
}
The View is still empty after calling notifydatasetchanged()
and I am not getting any error.
The List have around 800 objects.
Recycler View is showing null pointer exception, even after binding view using findviewbyID
Please post your xml layout and/or setting up recycler view code. Maybe there is no LayoutManager set. You may set it in xml or in the activity/fragment:
recyclerView.setLayoutManager(new LinearLayoutManager(this));
also try clearing your list in add_data()
list.clear()
list.addAll(..)
And modify your add_data function like this
fun add_data(data : StationsListDataClass){
list.clear()
list.addAll(data.stationBeanList)
notifyDataSetChanged()
Log.d("List", list.toString())
}
Update
Modify your setupRecycler like below
private fun setupRecycler(){
var recyclerView = findViewById(R.id.recycler_view_stations_list)
station_adapter = StationsListAdapter(this#StationsListActivity)
val layoutManager = LinearLayoutManager(this#StationsListActivity)
recyclerView?.layoutManager = layoutManager
recyclerView?.adapter = station_adapter
}

How can i write unit test for this actionfilter

public MyContext _db;
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (_db == null || !_db.ChangeTracker.HasChanges())
{
return;
}
try
{
_db.SaveChanges();
}
catch
{
}
}
This is my action filter for my wep api project. _db context object injected to this filter by per request. My point is here to call SaveChanges() method once after all processing done in service layers. My problem is how can test this filter? How can i mimic exception case that can happen in any controler or service layer and when exception throws saveChanges() never called? How can i setup the case that exception occurred in any place inside application?
I have been doing the same, last week, for my WebAPI 2 action filter.
I have an action filter that validates my ModelState and in case of any error it throws an error list with 200 HTTPcode.
The action looks like this:
public class ModelValidationActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid)
{
actionContext.Response = ...
}
}
}
UNIT TEST
var httpControllerContext = new HttpControllerContext
{
Request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/someUri")
{
Content = new ObjectContent(typeof(MyModel),
new MyModel(), new JsonMediaTypeFormatter())
},
RequestContext = new HttpRequestContext()
};
httpControllerContext.Request = new HttpRequestMessage();
httpControllerContext.Request.SetConfiguration(new HttpConfiguration());
var httpActionContext = new HttpActionContext { ControllerContext = httpControllerContext };
var filter = new ModelValidationActionFilterAttribute();
httpActionContext.ModelState.AddModelError("*", "Invalid model state");
// act
filter.OnActionExecuting(httpActionContext);
// assert
httpActionContext.Response.ShouldNotBe(null);
httpActionContext.Response.ShouldBeOfType(typeof (HttpResponseMessage));
var result = httpActionContext.Response.Content.ReadAsStringAsync().Result;
BaseServiceResponse<object> resultResponse =
JsonConvert.DeserializeObject<BaseServiceResponse<object>>(result);
resultResponse.Data.ShouldBe(null);
resultResponse.Messages.Count.ShouldBe(1);
resultResponse.Messages.First().Description.ShouldBe("Invalid model state");
In your case you need to Mock DB context using IDbContext interface - see here: http://aikmeng.com/post/62817541825/how-to-mock-dbcontext-and-dbset-with-moq-for-unit
If an unhandled exception occurs while executing the request then the Exception property on actionExecutedContext will contain the exception. This is part of the framework, and not something you need to test. In your tests you can simple set the Exception property manually and assert that the attribute takes the correct action.
[Fact]
public void Saves_data_on_failure()
{
var mockDbContext = new Mock<IDbContext>();
var myAttribute = new MyAttribute(mockDbContext.Object);
var executionContext = new HttpActionExecutedContext
{
Exception = new Exception("Request failed.")
};
myAttribute.OnActionExecuted(executionContext);
mockDbContext.Verify(d => d.SaveChanges());
}
You might also want to consider whether or not you want to save data for all types of exception. The data might be in an invalid/unknown state.

How to enable VersionCountDisabler for Glass Mapper in Sitecore for SitecoreQuery and SitecoreChildren attributes

The glass mapper will return null object or (no items) for SitecoreQuery and SitecoreChildren attribute that are placed on the GlassModels. These attributes don't take any such parameter where I can specify them to return items if they don't exist in the the context lanaguge. The items e.g. exist in EN but don't exist in en-ES. I need to put a lot of null check in my views to avoid Null exception and makes the views or controller very messy. It is lot of boiler plate code that one has to write to make it work.
In Page Editor the SitecoreChildren returns item and content authors can create items in that langauge version by editing any field on the item. This automatically creates the item in that langauge. However the same code will fail in Preview mode as SitecoreChidren will return null and you see null pointer exception.
SitecoreQuery doesn't return any items in page editor and then Content Authors wont be able to create items in Page editor.
To make the experience good if we can pass a parameter to SiteocreQuery attribute so it disable VsersionCount and returns the items if they dont exist in that langauge.
This is actually not possible. There is an issue on GitHub which would make it easy to create a custom attribute to handle this very easy. Currently you need to create a new type mapper and copy all the code from the SitecoreQueryMapper. I have written a blog post here about how you can create a custom type mapper. You need to create the following classes (example for the SitecoreQuery).
New configuration:
public class SitecoreSharedQueryConfiguration : SitecoreQueryConfiguration
{
}
New attribute:
public class SitecoreSharedQueryAttribute : SitecoreQueryAttribute
{
public SitecoreSharedQueryAttribute(string query) : base(query)
{
}
public override AbstractPropertyConfiguration Configure(PropertyInfo propertyInfo)
{
var config = new SitecoreSharedQueryConfiguration();
this.Configure(propertyInfo, config);
return config;
}
}
New type mapper:
public class SitecoreSharedQueryTypeMapper : SitecoreQueryMapper
{
public SitecoreSharedQueryTypeMapper(IEnumerable<ISitecoreQueryParameter> parameters)
: base(parameters)
{
}
public override object MapToProperty(AbstractDataMappingContext mappingContext)
{
var scConfig = Configuration as SitecoreQueryConfiguration;
var scContext = mappingContext as SitecoreDataMappingContext;
using (new VersionCountDisabler())
{
if (scConfig != null && scContext != null)
{
string query = this.ParseQuery(scConfig.Query, scContext.Item);
if (scConfig.PropertyInfo.PropertyType.IsGenericType)
{
Type outerType = Glass.Mapper.Sc.Utilities.GetGenericOuter(scConfig.PropertyInfo.PropertyType);
if (typeof(IEnumerable<>) == outerType)
{
Type genericType = Utilities.GetGenericArgument(scConfig.PropertyInfo.PropertyType);
Func<IEnumerable<Item>> getItems;
if (scConfig.IsRelative)
{
getItems = () =>
{
try
{
return scContext.Item.Axes.SelectItems(query);
}
catch (Exception ex)
{
throw new MapperException("Failed to perform query {0}".Formatted(query), ex);
}
};
}
else
{
getItems = () =>
{
if (scConfig.UseQueryContext)
{
var conQuery = new Query(query);
var queryContext = new QueryContext(scContext.Item.Database.DataManager);
object obj = conQuery.Execute(queryContext);
var contextArray = obj as QueryContext[];
var context = obj as QueryContext;
if (contextArray == null)
contextArray = new[] { context };
return contextArray.Select(x => scContext.Item.Database.GetItem(x.ID));
}
return scContext.Item.Database.SelectItems(query);
};
}
return Glass.Mapper.Sc.Utilities.CreateGenericType(typeof(ItemEnumerable<>), new[] { genericType }, getItems, scConfig.IsLazy, scConfig.InferType, scContext.Service);
}
throw new NotSupportedException("Generic type not supported {0}. Must be IEnumerable<>.".Formatted(outerType.FullName));
}
{
Item result;
if (scConfig.IsRelative)
{
result = scContext.Item.Axes.SelectSingleItem(query);
}
else
{
result = scContext.Item.Database.SelectSingleItem(query);
}
return scContext.Service.CreateType(scConfig.PropertyInfo.PropertyType, result, scConfig.IsLazy, scConfig.InferType, null);
}
}
}
return null;
}
public override bool CanHandle(AbstractPropertyConfiguration configuration, Context context)
{
return configuration is SitecoreSharedQueryConfiguration;
}
}
And configure the new type mapper in your glass config (mapper and parameters for the constructor):
container.Register(Component.For<AbstractDataMapper>().ImplementedBy<SitecoreSharedQueryTypeMapper>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemPathParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemIdParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemIdNoBracketsParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemEscapedPathParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemDateNowParameter>>().LifeStyle.Transient);
You can then simply change the SitecoreQuery attribute on your model to SitecoreSharedQuery:
[SitecoreSharedQuery("./*")]
public virtual IEnumerable<YourModel> YourItems { get; set; }
For the children you could either use the shared query mapper and querying the children or create the same classes for a new SitecoreSharedChildren query.
Edit: Added bindings for IEnumerable<ISitecoreQueryParameter> as they are missing and therefor it threw an error.

Unity PerRequestLifetimeManager UnitTest

I have following Unity configuration:
public static void RegisterTypes(IUnityContainer container)
{
...
container.RegisterType<IRootDatabaseContext, RootEntities>(new PerRequestLifetimeManager());
...
}
And everything works fine. But when I also want to test this method:
[TestMethod]
public void AssertUnityConfigAreValid()
{
using (var container = new UnityContainer())
{
UnityConfig.RegisterTypes(container);
foreach (var registration in container.Registrations)
{
container.Resolve(registration.RegisteredType, registration.Name);
}
}
}
And when I run this test I get an error:
InvalidOperationException - Operation is not valid due to the current state of the object.
How can I replace LifeTimeManager into Unit test from PerRequestLifetimeManager to another one?
I've just found the solution for this issue:
Just need to add following code before this line in test
UnityConfig.RegisterTypes(container);
var request = new HttpRequest("fake", "https://127.0.0.1", null);
var respons = new HttpResponse(new StringWriter());
var context = new HttpContext(request, respons);
HttpContext.Current = context;

How to call web service from flex

I have some problem with calling web service from flex. I have service with name UserService with one method string GetData(int i). I want to call this method from flex and get data. My code is here:
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
uService = new UserService();
uService.addEventListener("hello", echoResultHandler);
uService.GetData(1);
}
public function echoResultHandler(event:ResultEvent):void {
var retStr:String = event.result as String;
var retInt:int = event.result.echoInt;
Alert.show('want to play', retStr);
}
Might be my question is not difficult, but I can't understand why it does't works.. Can anybody help me?
Service code, generated by flex when I added reference to servese.
internal class _Super_UserService extends com.adobe.fiber.services.wrapper.WebServiceWrapper
{
public function _Super_UserService()
{
_serviceControl = new mx.rpc.soap.mxml.WebService();
var operations:Object = new Object();
var operation:mx.rpc.soap.mxml.Operation;
operation = new mx.rpc.soap.mxml.Operation(null, "GetData");
operation.resultType = String;
operations["GetData"] = operation;
_serviceControl.operations = operations;
try
{
_serviceControl.convertResultHandler = com.adobe.serializers.utility.TypeUtility.convertResultHandler;
}
catch (e: Error)
{ }
preInitializeService();
model_internal::initialize();
}
protected function preInitializeService():void
{
_serviceControl.service = "UserService";
_serviceControl.port = "BasicHttpBinding_IUserService";
wsdl = "http://localhost:3905/UserService.svc?wsdl";
model_internal::loadWSDLIfNecessary();
}
public function GetData(value:int) : mx.rpc.AsyncToken
{
model_internal::loadWSDLIfNecessary();
var _internal_operation:mx.rpc.AbstractOperation = _serviceControl.getOperation("GetData");
var _internal_token:mx.rpc.AsyncToken = _internal_operation.send(value) ;
return _internal_token;
}
}
Inherited class:
public class UserService extends _Super_UserService
{
protected override function preInitializeService():void
{
super.preInitializeService();
// Initialization customization goes here
}
}
Your UserService class never dispatches an event named "hello"; so therefore your result handler will never be fired. I think you need to add a result handler to the ASynctoken.
var call : Asynctoken = uService.GetData(1);
call.addResponder( new AsyncResponder(echoResultHandler) );
more info on the AsyncResponder and AsyncToken