Hey folks, i ve got this issue implementing the Factory method.
Following is the snippet of the the main chart class which calls ChartFactory's method to attain the proper object. I Type Cast chartobject so as to be able to call the Show method;i m apprehensive about that as well.
container = new VBox();
container.percentWidth = 100;
container.percentHeight = 100;
super.media.addChild(container);
chartObject = new ChartBase();
chartObject = ChartFactory.CreateChartObject(chartType);
IChart(chartObject).Show(o);
container.addChild(chartObject);
legend = new Legend();
legend.dataProvider = IChart(chartObject);
container.addChild(legend);
Following is the snippet of ChartFactory's method:
public static function CreateChartObject(subType:String):ChartBase
{
switch(subType)
{
case ChartFactory.AREA_CHART:
return new AreaCharts();
break;
case ChartFactory.COLUMN_CHART:
return new ColumnCharts();
break;
case ChartFactory.PIE_CHART:
return new PieCharts();
break;
default:
throw new ArgumentError(subType + ": Chart type is not recognized.");
}
}
And following is Show method of one of the several Charts type classes: AreaCharts, PieCharts etc. All of which implements IChart Interface.
public function Show(o:ObjectProxy):void
{
var grids:GridLines;
var stroke:SolidColorStroke;
var horizontalAxis:CategoryAxis;
var verticalAxis:LinearAxis;
var horizontalAxisRenderer:AxisRenderer;
var verticalAxisRenderer:AxisRenderer;
grids = new GridLines();
if(WidgetStylesheet.instance.LineChart_ShowGrid)
grids.setStyle("gridDirection", "both");
else
grids.setStyle("gridDirection", "");
stroke = new SolidColorStroke(WidgetStylesheet.instance.LineChart_GridLineColor, WidgetStylesheet.instance.LineChart_GridLineThickness);
grids.setStyle("horizontalStroke", stroke);
grids.setStyle("verticalStroke", stroke);
horizontalAxis = new CategoryAxis();
horizontalAxis.categoryField = o.LargeUrl.Chart.xField;
horizontalAxis.title = o.LargeUrl.Chart.xAxisTitle.toString();
verticalAxis = new LinearAxis();
verticalAxis.title = o.LargeUrl.Chart.yAxisTitle.toString();
horizontalAxisRenderer = new AxisRenderer();
horizontalAxisRenderer.axis = horizontalAxis;
horizontalAxisRenderer.setStyle("tickLength", 0);
horizontalAxisRenderer.setStyle("showLine", false);
horizontalAxisRenderer.setStyle("showLabels", true);
horizontalAxisRenderer.setStyle("fontSize", WidgetStylesheet.instance.ComputeChartAxisFontSize(o.HeadlineFontSize));
verticalAxisRenderer = new AxisRenderer();
verticalAxisRenderer.axis = verticalAxis;
verticalAxisRenderer.setStyle("tickLength", 0);
verticalAxisRenderer.setStyle("showLine", false);
verticalAxisRenderer.setStyle("fontSize", WidgetStylesheet.instance.ComputeChartAxisFontSize(o.HeadlineFontSize));
this.series = this.m_createSeries(o);
this.horizontalAxis = horizontalAxis;
this.horizontalAxisRenderers = [horizontalAxisRenderer];
this.verticalAxis = verticalAxis;
this.verticalAxisRenderers = [verticalAxisRenderer];
this.backgroundElements = [grids];
}
I'm afraid that there is more than one issue with this code. Unfortunately it is not obvious why your chart doesn't show up so you may apply some of advices below and use debugger to analyse the issue.
There is no point in creating ChartBase instance if you are going to change value of chartObject reference in the next line
chartObject = new ChartBase();
chartObject = ChartFactory.CreateChartObject(chartType);
If the API of your charts is IChart your factory should return IChart instead of casting.
public static function CreateChartObject(subType:String):IChart
Make sure that you are returning instances of the correct class from the factory. i.e. that you are returning your subclass of standard PieChart. Generally it's not the best idea to extend the class keeping the same name and just changing the package.
Once again, if you are not sure if the program enters some function use the Flash Builder debugger to check this. I can't imagine development without debugger.
Some thoughts:
you call the Show method, pass it some object but nowhere in that method is any child added to a displayObject. What exactly is Show supposed to do?
a lot of member variables in your classes start with UpperCase. The compiler can easily confuse those with class names, in case your classes are named the same. Bad practice to start variable and function names with capitals.
If your casting an instance to another class or interface fails, you will get a runtime error. Those are easy to debug using the Flash Builder debugger.
Hey ppl..
i found out wat wnt wrng..as olwys it wa "I".
I ve a habit of mkin mock ups secluded from the main project n dn integrate it. So in mock up i hd used an xml whch hd a format slightly diff dn d one being used in the main project.
N i hd a conditional chk to return from the prog if certain value doesnt match, n due to faulty xml i did'nt.
So this more a lexical error than a logical one.
Sorry n Thanx evryone for responding.
Related
I basically have this:
Obj1 Create event:
health_total = 50;
health_current = health_total;
health_text = instance_create(x,y-10,obj_health); // Object to show health of an instance object
health_text.origin = self; // Assign an 'origin' variable so I can access it later?
obj_health Draw event:
show_debug_message(origin.x); // <-- This works just great!
show_debug_message(origin.health_current); // <-- This throws error :(
I assume that the variable might be local but then, how do I make it public? GML is a bit new to me, though, I'm not new to programming. This makes my mind hurt.
Use id, not self:
health_text.origin = id;
I don't know why i'm having this behavior with my code coverage, maybe someone knows the reasson.
As you may know, code coverage is blue when reached, red when not reached, yellow when partially reached a line of code.
I coded a little mapper that receives a IDataReader and turns into object thanks to reflection.
internal IEnumerable<T> Convert<T>(System.Data.IDataReader dataReader) where T : new()
{
var columns = this.GetColumns(dataReader); // get a list of column name... not important.
var result = new List<T>();
while (dataReader.Read())
{
var nuevoObjeto = new T(); // <-- this line is yellow in code coverage.
foreach (var item in columns)
{
var pi = nuevoObjeto.GetType().GetProperty(item);
pi.SetValue(nuevoObjeto, dataReader[columns.IndexOf(item)]);
}
result.Add(nuevoObjeto);
}
return result;
}
As you can see, the yellow line is not a conditional like IF or WHILE... is just a simple "new T"
And if you debug this code, debug reaches very well that line, in fact test is green with expected results.
Test performs this steps.
Fake IDataReader (with nSubstitute)
Only 1 result on the datareader.
T is tested with only one TestClass... like USERTEST.
hope someone knows why this happens...
thanks!
The IL that gets generated for that line is equivalent to:
T nuevoObjeto = (default(T) == null) ? Activator.CreateInstance<T>() : default(T);
This allows structs to be used for the generic type as they satisfy the new constraint.
So, if you want 100% code coverage, test your generic method with a struct or change the constraint to require that the generic type be a class using where T : class
Try to test it also with struct or add class constraint to the generic method - http://www.codeproject.com/Tips/175592/Code-Coverage-And-Generics
This is a super newbie question on Flex. While I am a seasoned programmer, this is my first ever Flex application; please bear with me for my Flex codes.
I have a web service written in ColdFusion. In this web service, there are two functions; one is to return all the questions in a quiz and the other one is to return all the answer selections to the questions in a quiz.
[Bindable]
private var questionArray:ArrayCollection;
private var cfquiz:RemoteObject;
private function loadQuestions():void {
currentQuestionCounter = 0;
btnPrev.enabled = false;
btnNext.enabled = false;
cfquiz = new RemoteObject("ColdFusion");
cfquiz.source = "CFCertExam.cfquiz";
cfquiz.addEventListener(ResultEvent.RESULT, resultHandler);
}
private function resultHandler(event:ResultEvent):void {
questionArray = event.result as ArrayCollection;
txt1Questions.htmlText = questionArray.getItemAt(currentQuestionCounter).Question_Text;
btnNext.enabled = true;
}
I have the codes above. loadQuestions is called at creationComplete to retrieve the questions. Things are working fine. What I want to do is to call another function within the same web service, returnAnswers, to return the answer options for a question. Since I have cfquiz associated to the web service already, I was using cfquiz to call returnAnswers. However, there is an event listener associated to cfquiz already, resultHandler is being called when returnAnswers comes back with the results.
My questions are, first, is it possible to check which function returns the results within resultHandler? If so, how? And second, what is the best way to handle calls to multiple functions within the same web service?
Thanks in advance,
Monte
Yes you can. You need to specify a handler function for each method which in turn calls a different webservice.
The better way to do this is using AsyncToken and AsyncResponder instead of addEventListener, as following code.
tokenA = cfquiz.methodA();
tokenA.addResponder(new AsyncResponder(onResultForMethodA, onFaultMethodA));
tokenB = cfquiz.methodA();
tokenB.addResponder(new AsyncResponder(onResultForMethodB, onFaultMethodB));
tokenC = cfquiz.methodA();
tokenC.addResponder(new AsyncResponder(onResultForMethodC, onFaultMethodC));
or
tokenA = cfquiz.methodA();
var responderA:IResponder = new AsyncResponder(onResult, onFault, "methodA");
tokenB = cfquiz.methodB();
var responderB:IResponder = new AsyncResponder(onResult, onFault, "methodB");
tokenA.addResponder(responderA);
tokenB.addResponder(responderB);
private function onResult(evt:ResultEvent, token:Object):void {
if(token == "methodA" ) {
//logic for methodA
}
if(token == "methodB" ) {
//logic for methodB
}
}
I'm a little confused as I can't see where you are calling the actual web service function, for example from these examples, I am expecting to see:
cfquiz = new RemoteObject("ColdFusion");
cfquiz.source = "CFCertExam.cfquiz";
cfquiz.addEventListener(ResultEvent.RESULT, resultHandler);
cfquiz.myCFCFunctionCall(); /* where is this? */
Anyway, AFAIK you can create a new instance of the remote object and set that up to have it's own event listener.
Hope that helps.
What I'm doing NOW:
Often multiple instances of the view component would be used in multiple places in an application. Each time I do this, I register the same mediator with a different name.
When a notification is dispatched, I attach the name of the mediator to the body of the notification, like so:
var obj:Object = new Object();
obj.mediatorName = this.getMediatorName();
obj.someParameter = someParameter;
sendNotification ("someNotification", obj);
Then in the Command class, I parse the notification body and store the mediatorName in the proxy.
var mediatorName:String = notification.getBody().mediatorName;
var params:String = notification.getBody().someParameter;
getProxy().someMethod(params, mediatorName);
On the return notification, the mediatorName is returned with it.
var obj:Object = new Object();
obj.mediatorName = mediatorName;
obj.someReturnedValue= someReturnedValue;
sendNotification ("someReturnedNotification", obj);
In the multiple mediators that might be watching for "someReturnedNotification," in the handleNotification(), it does an if statement, to see
if obj.mediatorName == this.getMediatorName
returns true. If so, process the info, if not, don't.
My Question is:
Is this the right way of using Multiton PureMVC? My gut feeling is not. I am sure there's a better way of architecting the application so that I don't have to test for the mediator's name to see if the component should be updated with the returned info.
Would someone please help and give me some direction as to what is a better way?
Thanks.
I checked with Cliff (the puremvc.org guy) and he said it's fine.
I have an BLL that does validation on user input then inserts a parent(PorEO) and then inserts children(PorBoxEO). So there are two calls to the same InsertJCDC. One like this=>InsertJCDC(fakePor) and another like this=>InsertJCDC(fakeBox).
When I stub out the parent I want to return fakePor. But when I run the code it returns null instead. Here is the unit test.
[Test]
public void PorBLL_InsertByPorInsertCV_DoingGoodCase()
{
// Startup object mapper
_Bootstrapper.Bootstrap();
// create the mock for generic Crud
IGenericCrud mockGenericCrud = MockRepository.GenerateMock<IGenericCrud>();
PorInsertCV fakePor = new PorInsertCV();
PorBoxInsertCV fakeBox = new PorBoxInsertCV();
// build fake return
PorEO fakePorNewRow = new PorEO();
fakePorNewRow.PorId = 22;
// stub parent and child insert routines.
mockGenericCrud.Stub(c => c.InsertJCDC<PorEO, PorInsertCV>(fakePor)).Return(fakePorNewRow);
mockGenericCrud.Stub(c => c.InsertJCDC<PorBoxEO, PorBoxInsertCV>(fakeBox)).Return(null);
ObjectFactory.Inject(typeof(IGenericCrud), mockGenericCrud);
IPorBLL localWithMock = ObjectFactory.GetInstance<IPorBLL>();
// build user args to csll bll with and use for insert
PorInsertCV userArgs = new PorInsertCV();
userArgs.AccessionNbr = "364-80-0007";
userArgs.NbrBoxes = 11;
userArgs.RegId = 20;
userArgs.TransmitedDt = Convert.ToDateTime("1/30/1980");
// call the bll using the stub
localWithMock.InsertByPorInsertCV(userArgs);
}
Any help is greatly appreciated
I can't really follow your code that well, but I'll give it a shot.
From my skills of deduction, this line here is the one giving you issues:
mockGenericCrud.Stub(c => c.InsertJCDC<PorEO, PorInsertCV>(fakePor)).Return(fakePorNewRow);
Because you're expecting fakePorNewRow to be returned when you call localWithMock.InsertByPorInsertCV(userArgs); - yeah?
If that's your case, what your problem is, is that it will only return fakePorNewRow when it is given fakePor ... not userArgs as you have given it.
Tell me if I'm completely off track.
HTHs,
Charles
Ps. You might want to add the tag of which mocking framework you are using to the question.