Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Mediator not grabbing array from proxy, but the data is there...  (Read 14835 times)
garfu
Newbie
*
Posts: 6


View Profile Email
« on: March 17, 2009, 08:32:02 »

I got my first project sort of working. I am able to load a user object from a database and display it in a grid. I have a second proxy that is pulling other data, and supposed to put it in an array/ arraycollection, but as soon as I populate the data in the proxy, and call it from the mediator. It's null? I have also included the proper files, as the intellisense sees the _rolesProxy.groups

What am I missing?

Proxy (traces array of 6 objects)
:

public var _roles:Array;
public var _groups:Array;

public function get roles():Array
{
return this._roles;
}
public function get groups():Array
{
return this._groups;
}

private function _onGetRoleResult(e:ResultEvent):void
        {
        try {
        trace("Roles Loaded " + e.result.group);
this._roles = e.result.role;
this._groups = e.result.group;
this.sendNotification(ApplicationFacade.ROLES_LOADED);
} catch(error:Error) {
trace('onResult error: ' + error.message);
}
        }


Mediator (traces NULL)
:
private var _roleProxy:RoleProxy;

case ApplicationFacade.ROLES_LOADED:

rolePanel.userRoles = this._roleProxy.roles;
rolePanel.userGroups = this._roleProxy.groups;
trace("groups " + this._roleProxy.groups);
break;
« Last Edit: March 17, 2009, 08:44:50 by garfu » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: March 18, 2009, 04:33:15 »

I don't see anything obvious here. Are you using FlexBuilder? If so, I suggest ditching the trace approach and pick up the debugger tool. Set a breakpoint on the line in the proxy where the result event comes back and then step through the code one line at a time until you reach the mediator's response to the ROLES_LOADED note. Inspect the variables in both places and along the way and see where you dropped the ball.

Be sure to turn on 'Flex->Show inaccessable members' on the Variabls view dropdown menu or you won't be able to see everything.

-=Cliff>
Logged
garfu
Newbie
*
Posts: 6


View Profile Email
« Reply #2 on: March 18, 2009, 07:39:22 »

Thanks for the reply, and yes I am using Flex Builder. This is the infuriating thing. Immediately after that notification is sent, it goes to the mediator and I check the data from the reportProxy, and it == null as soon as I hit the mediator, and after it tries to load that data into the panel.

I turned on the show inaccessible members, but it goes straight from my proxy here:

this._roles = e.result.role as Array;
this._groups = e.result.group as Array;
this.sendNotification(ApplicationFacade.ROLES_LOADED);
...
to a few pages of not found, lookup source path. (Your send notification code)
...
to the case statement. And in my breakpoints, it shows all the data populated perfectly in the proxy, but as soon as it hits the mediator, boom. Null.

I have been playing with your EmployeeAdmin demo, but just trying to modify it to use a DB instead of that dummy data for my own practice. It works well right up until I tried to modify the RoleProxy and get back db data.
« Last Edit: March 18, 2009, 07:41:07 by garfu » Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #3 on: March 18, 2009, 08:06:43 »

@garfu

I guess you already retrieved the proxy in your mediator?
private var roleProxy:RoleProxy;      
---
roleProxy= facade.retrieveProxy( RoleProxy.NAME ) as RoleProxy;
---
and then did this:
rolePanel.userRoles = roleProxy.roles;

?
Logged

~ Ondina ~
garfu
Newbie
*
Posts: 6


View Profile Email
« Reply #4 on: March 18, 2009, 08:42:07 »

Correct, that line is in the constructor. Sorry i forgot that in the original post.
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #5 on: March 18, 2009, 09:44:04 »

Well then I would check again if  e.result.group and e.result.role are really arrays.
Logged

~ Ondina ~
garfu
Newbie
*
Posts: 6


View Profile Email
« Reply #6 on: March 18, 2009, 10:01:50 »

They are. I have split them into two calls. One for groups, and one for roles.

I split the two calls into groups & roles to see if that helped. it didn't. Here is the new method with it's trace result
:
private function _onGetGroupResult(e:ResultEvent):void
        {
        trace("Groups Loaded " + e.result);
//this._roles = e.result.role as Array;
this._groups = e.result as Array;
this.sendNotification(ApplicationFacade.GROUPS_LOADED);
        }
Groups Loaded [object Object],[object Object],[object Object],[object Object],[object Object],[object Object]


Here is a screenshot of what returns from Charles.


But yet as soon as it get's to the case statement, this._roleProxy.groups & this._roleProxy.roles is null when I breakpoint in Flex Builder. As you can see, it goes directly from the RolesProxy to the RolePanelMediator

:
case ApplicationFacade.GROUPS_LOADED:
rolePanel.userGroups = new ArrayCollection(this._roleProxy.groups);
trace("groups Mediator " + this._roleProxy.groups);
break;
groups Mediator null




Logged
garfu
Newbie
*
Posts: 6


View Profile Email
« Reply #7 on: March 18, 2009, 10:22:12 »

I was using the same swc as the demo. 2.0.1

I am using 2.0.4, and if I pass the this.groups into the sendNotification, and do note.getBody in the Mediator, I can see the array. I will adjust the code to handle it this way, but I still cannot just do a this._roleProxy.groups in the Mediator.

But as long as it works....
Logged
Ondina
Sr. Member
****
Posts: 86


View Profile Email
« Reply #8 on: March 18, 2009, 12:11:25 »

Yes it's probably better to pass it into the sendNotification, and do note.getBody in the Mediator, at least that's how the most puremvc examples do it.

Looking at your code... ..there are different  settings  in your Proxy and Mediator and I don't know exactly which one is the final version.
I think you mixed them up somewhere and then in your mediator you expected one data type but got another. 

In one place you have
this._roles = e.result.role as Array; ( e.result.role is an Array or an Object?)
then this
this._groups = e.result as Array;

In private function _onGetRoleResult(e:ResultEvent):void
e.result is an Object

I would add the e.result Object to an ArrayCollection in my Proxy and would pass it into the Notification.
And then I would make eligible for garbage collection everything that I wouldn't need anymore in that Proxy.

But if you want to retrieve the proxy's variables directly in the Mediator, you just have to return the expected data type in your
public function get roles()
and
public function get groups()
so the mediator can work with it.

So I think:)
Logged

~ Ondina ~
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #9 on: March 18, 2009, 05:25:41 »

It may not the problem, but you should override nRegister in the Mediator and retrieve the proxy there. I know it is currently in the constructor in EmployeeAdmin, but it takes time for the demos to catch up with best practices.

When MultiCore came out this became necessary there because the INotifiers can't get their facade references until after construction. This is because there are many facades and an actor can't retrieve their facade until they get their multiton key.

So that constructor facade call would barf in multicore.

But that brought to light a better practce. If you create a mediator, and before it is registered, it retrieves a proxy and makes a call that results in a notification coming back, if the mediator isn't yet registered, it won't receive the note!

So definitely move the call to onRegister. This also goes for adding event listeners. If you add an event listener to ta component in the constructor and the user makes a click that raises an event before the mediator is registered, then the event handler in the mediator may also initiate a conversation that the mediator will not be prepared to participate in.

Abyway, back to debugging, when you are in the proxy, after receiving the result and hitting your breakpoint, you can open the facade, drill down through the model, and its proxyMap, into the proxy we're stopped in (yes, its also 'this', but we want to be sure its propely registered as well),  and see your data?

And then you can step through until you're in your mediator's handleNotification switch and drill down through the facade, view, mediatorMap, into this mediator, and see its local reference to the proxy in question and now that data is gone? Or are you looking at the variable you set with data from the proxy and its null? The latter could fail due to your getter in the proxy not returning the right thing or a failure to cast properly.

-=Cliff>
Logged
garfu
Newbie
*
Posts: 6


View Profile Email
« Reply #10 on: March 20, 2009, 10:43:25 »

Sorry for taking so long to reply, but wow, this is all excellent info. Perhaps some of the things you listed is why I currently can't save any of the records to the database. It seems to be falling along the same lines. as I step through the code, it's all populated in the form, when I dispatchEvent and it goes to the mediator, none of the modified data is carried over, so there are no changes. I will make some changes based on your comments and see what happens.

Also, When I hit the breakpoint in the Proxy, drilling down to this.facade is empty. The only thing in there is the data I populated from the DB call.


Here is the saving of data.
:
private function submit( ):void
{

var saveUser:UseraccountVO = new UseraccountVO();
saveUser.userName = username.text;
saveUser.firstName = first.text;
saveUser.lastName = last.text;
saveUser.email = email.text;
saveUser.password = password.text;
                                        saveUser.userRank = rank.text;

if ( mode == MODE_ADD )
{
dispatchEvent( new Event( ADD ) );
} else {
dispatchEvent( new Event( UPDATE ) );
}


I changed the UserFormMediator to have:
:
override public function onRegister():void
{
userForm.addEventListener( UserForm.ADD, onAdd );
userForm.addEventListener( UserForm.UPDATE, onUpdate );
userForm.addEventListener( UserForm.CANCEL, onCancel );

userProxy = facade.retrieveProxy( UserProxy.NAME ) as UserProxy;
}
And I am attempting to do a simple update. But the new data isn't reaching the mediator. Again, I put a breakpoint in the form in the submit function, and i see all the text field new data going into this saveUser object. it fires the event, makes it to the mediator here:
:
private function onUpdate( event:Event ):void
{
var saveUser:UseraccountVO = this.userForm.saveUser;
userProxy.save(saveUser);
sendNotification(  ApplicationFacade.USER_UPDATED, saveUser );
clearForm();
}

When I breakpoint there, I see no saveUser??? It only has user, and this.user, and the data contained in user is the original. In my form, It's definitely there, intellisense sees it. So I am looking into more than use registering those listeners and the proxies in the onRegister override methods in mediators. If anything jumps out as being incorrect or out of order, please help.

UserForm.mxml
:
[Bindable] public var saveUser:UseraccountVO;
[Bindable] public var user:UseraccountVO;
[Bindable] public var mode:String;


<edit> It seems as though my bin-release and bin-debug weren't configured properly. all is well. initializing stuff on register now. Thanks for the tip, I printed off best practices today.




« Last Edit: March 20, 2009, 05:20:55 by garfu » Logged
Pages: [1]
Print