Hi David,
Thank you so much for your detailed explanations! The e-mail you
wrote provided me with all the resolutions to pending problems plaguing
my database application. I am eternally grateful for all of your
help! And you've helped to shed light on the incorrect ways I've been
building my implementations.. Thanks again!! :)
Best regards,
Janice
David LeBer wrote:
On 20-Oct-05, at 11:59 AM, Janice Cheung wrote:
Hi David!
Thanks for your input. I really appreciate your advice!
David LeBer wrote:
My head hurts.
I wrote out a great long-winded email about flattened attributes and
relationships an setter and getter method names. But I think I need
to stop now.
This is what I think you are trying to do. You are trying to take
arrays of objects and reduce their values to comma separated strings
for some reason. Why? I don't know.
Yes, I am trying to take arrays of objects and reduce their values
to comma separated strings. This is for a client request to provide
an editable text field where values of objects (email contacts,
specifically) are displayed for an end user to add new e-mail
addresses (Strings) to
send out broadcast messages.
I have something like this on an Email Contacts HTML page (four
editable text fields):
From: (session.currentUser WOTextField)
To: (server.getEmailContacts WOTextField)
Subject: (subject WOTextField)
Body: (htmlMsg WOTextField)
I am NOT trying to save the server.getEmailContacts text field to
the database in this EmailContacts HTML page. I am merely trying to
provide the end user with the functionality to append any
additional strings/email addresses to the server.getEmailContacts
WOTextField.
For example, in my To: field, I will have something like
To: "email@hidden, email@hidden" (server.getEmailContacts
WOTextField)
Now, an endUser will mosey along and say, 'Why, I'd like to add
email@hidden to the e-mail contacts values'. In the
WOTextField, endUser
will add, "email@hidden" to "email@hidden, email@hidden". However,
when I click on my "sendMail" submit button, "email@hidden"
is not appended to the getEmailContacts string, and poor
"email@hidden" doesn't receive any e-mail notifications, unbeknownst to
endUser.
I do not know why this is not working properly... (I've replaced
my mess of code with Chuck's elegant solution already too).
OK, I wouldn't do it this way :-)
The thought of having a long comma separated string subjected to the
editing whims of a user just gives me the heebeegeebees (technical
term).
Keep the array of email addresses as an array (that's what your going
to need when you send it to WOMailDelivery anyway). Make a mutable
copy (NSMutableArray) of it for your component and then do the
standard WORepetition wrapping WOString thing to show the user the
auto-populated addresses. Give the user an "add email address" button
and field that allows them to add more addresses to this
"recipientEmailAddresses" array and perhaps a "remove address" button
nested in the repetition as well.
This would be *much* cleaner, require less code and allow far easier
validation on properly formed email addresses too.
Once you've got your final NSArray of addresses you can hand it off to
WOMailDelivery without further manipulation.
If you are receiving an array of objects
and you need to display their values separated by commas then use a
WORepetition and have it build the presentation for you. That's what
it's there for (and you write no code).
Yes! I am using a WORepetition already to display values of
objects that are NOT separated by commas. To clarify, there is no
need for any comma separated
strings of my values to go back to my database again. The comma
separated strings are only used for the EmailContacts HTML page. I
have a ViewServerDetail
HTML page that contains two WORepetitions, with various string
values of objects pulled from the database. Instead of something
like server.getEmailContacts(),
I have two WORepetitions with the following bindings:
Repetition1: WORepetition{
item=m_ServerContract;
list=server.serverContracts;
}
TextField1: WOTextField{
value=m_serverContract.contact.fullName;
}
TextField2: WOTextField{
value=m_serverContract.contact.email;
}
Hypothetically, the values within these WOTextFields should also
save properly with saveChanges() to the database. However, changes to
these text fields
are not being updated, but only for one of the two WORepetitions
(which are identical aside from the fact that one is filtered by
Conditionals for billing Contacts,
while the other is filtered by Conditionals for administrative
contacts). Specifically, Billing Contact edits are being saved, but
AdministrativeContacts are not,
although they are using the same WORepetition and textField
values.
In addition, other TextFields (which also do not contain any comma
separated values) that return object values are not saving to the
database. These are also
based on flattened relationships.
More specifically, I have something like this:
public String getSerial(){
NSArray pc=(NSArray)storedValueForKey("toDevice");
java.util.Enumeration e=pc.objectEnumerator();
String serials="";
while (e.hasMoreElements()){
Device dev=(Device)e.nextElement();
if (dev.serialNum()!=null){
serials=serials+((dev.serialNum()));
}
}
return serials;
}
Stop doing this. No really, it the cause of all of your woes. If you
have multiple serial numbers (or anything else for that manner) treat
them as individual entities and stop trying to flatten them into a
single String.
and in my binding, I have:
TextField3: WOTextField{
value=server.getSerial; /*
--------------------------------THIS WON'T SAVE : (
------------------------------------*/
}
Of course it won't. On submit WO will try and take the value from the
WOTextField and put it into... getSerial! That's a getter method.
Without a corresponding setter method (that some how magically figures
out how to parse your flattened string back into the correct original
objects).
However, if I re-write TextField3 in the
following manner the value will save correctly:
TextField3: WOTextField{
value=server.toDevice.serialNum /*
-------------------------------- THIS WILL SAVE!
------------------------------------*/
}
The reason why I opted not to retrieve the serialNum values in
this manner is because the WOTextField will return with an infinite
number of parentheses and
quotes (something like this) upon each incremental save:
("("("78-0lys1231251")")")
When you call toString() on an NSArray you will get this:
("ValueAtIndex0", "ValueAtIndex1","ValueAtIndexN") So what you are
seeing is expected.
So lets look at this:
Server ---------toDevice------->> Device.serialNum
Server has a toMany relationship to Device, which has a serialNum
attribute. That toMany relationship is going to return an NSArray of
Devices for your Server. If there will only ever be *one* device and
that is the one you want the serialNum for then do this:
// In Server
public Device primaryDevice() {
NSArray array = toDevice();
if (array != null && array.count() > 0) {
return (Device)array.objectAtIndex(0);
}
return null;
}
Then bind your WOTextField to server.primaryDevice.serialNum
If you expect multiple Devices for each Server, then build your
components to handle that (You know, the WORepetition drill).
which would appear somewhat dizzying and undesirable for endUsers
to peer at.
Am I missing something trivial? Am I overlooking things and
barraging too much messy code on my project? I am sorry I am baffling
people with my wayward
means of implementation... but I really appreciate any help and
advice.
Thank you very much for your time and attention to this important
matter.
Kindest regards,
Janice
I think this is a really lousy idea. For you to be able to go from a
string back to your array of serverContracts (and then to their
contact.fullNames) you will need to guarantee that the order of the
serverContracts array has not changed. I cannot do that, can you?
Really. You should try to keep objects as objects for as long as
possible, when you reduce them to something flat you lose their
identity and then it become really hard to return.
--
;david
--
David LeBer
"I am codeferous!"
Codeferous Software
site: http://www.codeferous.com
blog: http://david.codeferous.com
--
;david
--
David LeBer
"I am codeferous!"
Codeferous Software
site: http://www.codeferous.com
blog: http://david.codeferous.com
|