This week's book giveaways are in the Scala and Android forums.
We're giving away four copies each of Machine Learning Systems: Designs that scale and Xamarin in Action: Creating native cross-platform mobile apps and have the authors on-line!
See this thread and this one for details.
Win a copy of Machine Learning Systems: Designs that scale this week in the Scala forum
or Xamarin in Action: Creating native cross-platform mobile apps in the Android forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Object passed with commandLink lost on click  RSS feed

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone!

I have to use JSF for a school project and I'm a complete beginner.

From what I understood of my problem while debugging, I think I simply don't understand how JSF requests works...

My application is a simple contacts manager, I have a main page with a table containing all the contacts and for each on them, a view, edit and delete button.
All my beans are actually request scopped.

I've made the main page edit buttons works with a simple :

Where "c" is my dataTable var. It works perfectly and the edit form is well loaded with the contact data.

I've used the same commandLink style for the view page, and it works, the contact is well passed to my ShowContactBean and the data are displayed.
But this page contain an edit button too, and this one is not working, despite being like the other one:

Where contactBean is my contact form bean (for creating and editing) and showContactBean is the bean managing the view page, where the button is.
I've first tried by passing the contact object directly (showContactBean.contact) bug I thought that because objects are just references, the objects was lost between those three pages, so I've tried with the id.

I don't think the bean code is revelant here because it is very simple and works from the main page but just in cas, here is the edit methods :


The edit button from the view page lead me to the edit page but without passing the data, when I'm debugging I can se that my contactBean.setContact() is receiving a int 0 parameter (or a null contact when I was trying with the object).
But the ShowContactBean had the contact just before, because it successfully showed it to me.
I've also realized that the showContact bean is called before the contactBean when I click on the button, I don't understand why, but by calling itself with no parameters it is obviously reinitializing all its attributes.
I suppose my whole problem came from this misunderstanding...

It has been hard for me to explain this problem, I had difficulties to even detect it and more considering english isn't my mother tongue. So if something is unclear (likely), please let me know.

Thanks a lot forany help!

J.
 
Bartender
Posts: 19458
88
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
JSF does not work by "passing parameters". Instead, JSF employs the Model/View/Controller architecture.

In MVC, changes to the controls in the View update their corresponding values in the Model (Backing Bean). Likewise, changes in the Model update the control values in the View.

Since this is operating under HTTP, however, it takes manual action (a form submit) to accomplish this. Unlike desktop MVC systems, HTTP cannot asynchronously make View changes or see View changes - only a request/response cycle can do this.

Because many controls are both read and written, function call representation of the control values on the form don't work. Instead, the Expression Language (EL) supports property references. That is:



Would have to be


JSF will automatically invoke getXyz() on the bean to obtain the value to display and it will also automatically invoke setXyz() on the bean when the form is submitted. You do not have to (and shouldn't!) write any actual code to transfer the data between the form and backing bean. This is part of JSF's Inversion of Control architecture. IoC is a common and popular way of programming where data is manipulated by external mechanisms (the JSF control framework) as opposed to having to hard-code the data manipulation in application logic.

Because JSF automatically brings the values on the form and the values in the backing bean(s) into sync when a form is submitted (via commandButton or commandLink), you don't submit using a function call or parameters, you use a method reference.

That is:


Will initiate the JSF lifecycle processing. JSF will validate the data on the form, and if (and only if) [i]all[/b] control values are valid, it will then update the backing bean with those values. JSF will then invoke the doSomething() method and the doSomething method can proceed confident that all the data that was entered is available as property values within the backing bean.

It's a general rule that the more work and the more JSF-specific code that you create, the more likely that you're doing it wrong. JSF is very automatic.
[/code]

 
James Kelington
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim and thanks a lot for that explanation!

However, I think you didn't understand my entire problem, or I didn't understand your whole answer which is possible too!
I've applied this principle on most of my forms, but here I need another bean to know which contact I want to edit.
I've found the solution of calling the bean method and passing the object to it on stackoverflow and it works perfectly on my main page.

When clicking on the edit button in a row of my main view dataTable, the contact is passed to the edit method of my ContactBean and it works.

When clicking on the view button in the same row, the same process applies and I'm calling my ShowContactBean method "show" => the data are displayed.
But from this page, I have another edit button, using the same principle as the main one, but when calling the ContactBean edit method from there, I always get a null parameter in my ContactBean...

From what I understood of your answer, you're telling me that I shouldn't need to manually call these methods of my beans but I don't know how to do what I want without that... It is very frustrating because in my head my needs are very simple but I just can't figure out a way to pass the contact I want to view/edit between those three pages...

Thanks again for your help, hope you'll have the time to help me more

J.
 
Tim Holloway
Bartender
Posts: 19458
88
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I usually do have to do several cycles on questions like these. When I see obvious violations of JSF operating principles, I tend to focus on them first.

One of the magical things about MVC is that a View can be backed by multiple Models and a Model can be backed by multiple Views. It's not strictly one-to-one.

One of my favorite examples is a View that contains 2 sub-views of the same Model. One as a spreadsheet and one as a piechart. Change a cell in the spreadsheet, presto! The piechart gets re-drawn too.

In your case, I'm reading it that you have 2 distinct JSF Managed Beans. No problem. You can use them both as backing beans on the same view, no problem. To get information from one bean into the other, you simply inject the first bean as a ManagedProperty into the second bean. So if you have a bean that manages an editor session (editBean) and another bean that holds the actual data being edited (dataBean), then the editBean form can update the data bean's properties via EL like this:


And JSF will do the rest.

Likewise, if editBean has an action method named doEdit(), then the edit code can access the data like so:
 
Tim Holloway
Bartender
Posts: 19458
88
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, almost forgot.

One limitation. JSF works with forms, and when you submit a form, only data in that form gets submitted. No data from any other form on the page will be submitted, and therefore backing bean data from other forms will not be updated.

This is actually a restriction of HTML forms. JSF is based on HTML, so it inherits HTML's limitaitons.
 
James Kelington
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot this is really obvious in my mind now!
I really didn't understand how jsf works, it's clearer now.

Thanks again!
 
What's that smell? I think this tiny ad may have stepped in something.
Rocket Oven Kickstarter - from the trailboss
https://coderanch.com/t/695773/Rocket-Oven-Kickstarter-trailboss
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!