is it possible save and get next record in one action

is it possible save and get next record in one action

  

Hi All,

i want to ask about save data,

the scenario like this, data already exist and i will changes the data,

for example :

id : 01
name : risa
age : 20

id : 02
name putri
age : 17

I changes data risa from 20 to 25, and i save the data 

when i save data risa, in the same form data putri was appear

is it possible in outsystem ??

Hi,

You mean, you want to show both information at the same time?

It is possible, but probably a bad interface design (unless you are using Editable Tables)

I recommend you to attend a live OutSystems class or do the online classes (they are for free), as those subjects (like saving data) are presented and discussed in them.

https://www.outsystems.com/learn/paths/

Cheers

Eduardo Jauch

Eduardo Jauch wrote:

Hi,

You mean, you want to show both information at the same time?

It is possible, but probably a bad interface design (unless you are using Editable Tables)

I recommend you to attend a live OutSystems class or do the online classes (they are for free), as those subjects (like saving data) are presented and discussed in them.

https://www.outsystems.com/learn/paths/

Cheers

Eduardo Jauch

Hi Mr. Eduardo,

Thank you for your reply,

what i mean is the data was appear alternately, after i update and save the first data,
next record was appear

after i click button update and save, data risa was change and data putri was appear in the form

is it possible ?

Thanks

Risa

Yes, it is certainly technically possible.

I think the point Eduardo is trying to make is that from a user's point of view it could be confusing. But if that is the way you/they want it to work, then you could certainly implement it like that.

After the save, query the data for the next record, and refresh your form with an ajax refresh. That should do the trick.

Risa

If the entity is order by ids you can query the entity demanding the record with bigger Id, limited to one record.


Hope it help

Hi Tim,

I would do exactly as you mentioned, however i have a question that, what would be the best way to fetch the next record? 

Is it like I have to write my own logic to get the next record may be using Current ID + 1 or something like that or other way like i get the full record set and i iterate on it?


Shashank...

Hi,

Maybe it can be done without querieng. in the save action you can put as last step a destination screen that's the same screen where you're in. As Id you do something like this:

LongIntegerToIdentifier(IdentifierToLongInteger(CompanyId) + 1)

I am an Outsystems beginner, so I don't know what the experts say if this is a proper solution, but it seems to work (you may have to tweak it though).

Regards, Harry 

Hi Harry,

I am worried about cases where i don't want ID + 1 because the next ID record might not be an active record [due to a delete].

So i am thinking towards a solution where I get the record set in one shot with my specific condition [i.e. Fetch all active records] and iterate that record set by NextRecord or something.


Shashank...

Risa and Shashank,

I'll will strongly recommend you both to do the training and study the documentation, as this will enable you to find those answers by your self.

Said that, no, as you can't guarantee the ID will be sequential.

The best would be to fetch all records, and use the current as source to the form. In the save (that should be a Submit, to make it easier), you would, at the end, increment the current to the next record using an assignment to do something like this:

1. GetYourData.List.CurrentRowNumber = GetYourData.List.CurrentRowNumber + 1
2. GetYourData.List.Current = GetYourData.List[GetYourData.List.CurrentRowNumber]
3. YourForm.Record = GetYourData.List.Current

As it is a submit, the form will be refreshed and will show the new data.

The problem here is that you are USING data from an aggregate in the preparation. This causes more traffic in the network.

A possible alternative (and probably best) would be having a field in the entity that you mark as processed, and in the preparation you fetch in the aggregate only records not processed, with the MaxRecords property set to 1 (ordered the way you think it is best).

Than in the Save action, you execute a new aggregate in the SAVE, but exactly the same as the one in preparation, and change the form the way described before.

This way you are always fetching only a single record and do not increase network traffic.

Cheers,

Eduardo Jauch

Harry de Boer wrote:

Hi,

Maybe it can be done without querieng. in the save action you can put as last step a destination screen that's the same screen where you're in. As Id you do something like this:

LongIntegerToIdentifier(IdentifierToLongInteger(CompanyId) + 1)

I am an Outsystems beginner, so I don't know what the experts say if this is a proper solution, but it seems to work (you may have to tweak it though).

Regards, Harry 

Or you could create a webblock (with an Id as input) in which the form resides, then when saving you send a notify to the parent webblock/screen. Then on the notify handler you just get the next Id from your list and Ajax Refresh the webblock which contains the form.

There are multiple ways to get the next Id on a list, for instance get a variable, set it to 0, write an if statement, check if Counter < (List.Length - 1).

If true you Do something like IdForMyWebBlock = List[Counter].Id
Afterwards you refersh the WebBlock.
On each new notify you just do Counter = Counter + 1.


All,

it seems to me that what seems to be an easy question requires some work to get it working. In other languages you should just say: Table.Next (or something like it). Should we propose this as an Idea to OS (a set of actions like .Next, Previous, First, Last) or is it not such a big deal?

Regards Harry 

Hi Harry,

In other languages when you use the Something.next, the records are already in memory and not in the database.

You can do the same in here by getting the records in a list and iterate through the list using an index (as stated above in other posts). Of course this is only a solution if the number of records is not that large. Otherwise you should go with other of the solutions above.

Cheers,

José

Solution

hi Putri,

What are said by the experts above are correct:

1. It is better to use 'best design pattern' as tutorred from the OS learning course.

2. Use Editable Tables for updating more than one record.

Just in case it is your 'strict' business requirement, here we go:

Given:

Find:

Solution:

1. Create a New Screen- Next Human - and in the preparation action put aggregate with the following filter:

2. Do not forget to set the Max Records property with value 1 - the record to be the next one to be updated

3. In the Update button, just assign the UpdatedDate to currDate() and let the control back to the Next Human screen (current screen):


.oml is attached

regards,

bb

Solution

Hi Eduardo,

I mentioned the same thing that i can get the full record set and iterate on it but just like you said it may create traffic issues since data size can be huge.


"A possible alternative (and probably best) would be having a field in the entity that you mark as processed, and in the preparation you fetch in the aggregate only records not processed, with the MaxRecords property set to 1 (ordered the way you think it is best)."

In your possible workaround, adding a field and mark it processed is also not going to work since different users may do the same activity, meaning it is not necessary that only once the data has to be updated.


I think getting the next ID with a logic [with all conditions defined and get the next Id from current] will be easier due to above scenarios.


Shashank...

Shashank Diwan wrote:

Hi Eduardo,

I mentioned the same thing that i can get the full record set and iterate on it but just like you said it may create traffic issues since data size can be huge.


"A possible alternative (and probably best) would be having a field in the entity that you mark as processed, and in the preparation you fetch in the aggregate only records not processed, with the MaxRecords property set to 1 (ordered the way you think it is best)."

In your possible workaround, adding a field and mark it processed is also not going to work since different users may do the same activity, meaning it is not necessary that only once the data has to be updated.


I think getting the next ID with a logic [with all conditions defined and get the next Id from current] will be easier due to above scenarios.


Shashank...

It's always a case of context (that we didn't have previously).

Thirst thing, if you have multiple users updating the same records, well, this will be a mess, no? :)
Like, If two or more users change the same field, at the same time, for different values, who will have priority? 

You see? Its a problem of business logic, not only of technique. 

There are multiple ways of doing the same thing. 

Using iteration will usually be a bad solution, because who knows in the future how many people will use the application, or how many rows will be fetched. Your application becomes harder to scale. 

So, the path is to fetch a single record at a time.

If having a field that mark as processed is not suitable for the business logic, and knowing that we can't relay on ID sequence, we still can work looking ONE record at a time. You just need to order the way you want and when fetching the next one, use some information from the previous to remove it from the result or to tell where to start looking for records.

The editable table is a solution, but for too many records is annoying and if you need to do "special" things you will face lots of problems.

Cheers,
Eduardo Jauch


Eduardo Jauch wrote:

Shashank Diwan wrote:

Hi Eduardo,

I mentioned the same thing that i can get the full record set and iterate on it but just like you said it may create traffic issues since data size can be huge.


"A possible alternative (and probably best) would be having a field in the entity that you mark as processed, and in the preparation you fetch in the aggregate only records not processed, with the MaxRecords property set to 1 (ordered the way you think it is best)."

In your possible workaround, adding a field and mark it processed is also not going to work since different users may do the same activity, meaning it is not necessary that only once the data has to be updated.


I think getting the next ID with a logic [with all conditions defined and get the next Id from current] will be easier due to above scenarios.


Shashank...

It's always a case of context (that we didn't have previously).

Thirst thing, if you have multiple users updating the same records, well, this will be a mess, no? :)
Like, If two or more users change the same field, at the same time, for different values, who will have priority? 

You see? Its a problem of business logic, not only of technique. 

There are multiple ways of doing the same thing. 

Using iteration will usually be a bad solution, because who knows in the future how many people will use the application, or how many rows will be fetched. Your application becomes harder to scale. 

So, the path is to fetch a single record at a time.

If having a field that mark as processed is not suitable for the business logic, and knowing that we can't relay on ID sequence, we still can work looking ONE record at a time. You just need to order the way you want and when fetching the next one, use some information from the previous to remove it from the result or to tell where to start looking for records.

The editable table is a solution, but for too many records is annoying and if you need to do "special" things you will face lots of problems.

Cheers,
Eduardo Jauch


Hi Eduardo,

I agree with you, honestly i wont go for a feature like it where someone wants to edit record sequentially, as it the usual practice is List and Edit. Other options is editable tables.


Shashank...




Harry de Boer wrote:

All,

it seems to me that what seems to be an easy question requires some work to get it working. In other languages you should just say: Table.Next (or something like it). Should we propose this as an Idea to OS (a set of actions like .Next, Previous, First, Last) or is it not such a big deal?

Regards Harry 


I agree, when you have a list or aggregate it would be awesome to have a previous or next.
This would save alot of trouble when trying to get the next index, since you have to do some validation in before going to the next element.

I'm pretty sure outsystems uses arrays for lists where the current is some pointer to the current index of the array.
Next and previous would simple shift this value.

Claring wrote:

Harry de Boer wrote:

All,

it seems to me that what seems to be an easy question requires some work to get it working. In other languages you should just say: Table.Next (or something like it). Should we propose this as an Idea to OS (a set of actions like .Next, Previous, First, Last) or is it not such a big deal?

Regards Harry 


I agree, when you have a list or aggregate it would be awesome to have a previous or next.
This would save alot of trouble when trying to get the next index, since you have to do some validation in before going to the next element.

I'm pretty sure outsystems uses arrays for lists where the current is some pointer to the current index of the array.
Next and previous would simple shift this value.

As was stated before (I think), this kind of functionality makes sense when you fetch a set of records.
You can do something VERY similar in a List. You can iterate through the list and set Current to the next one.

But for the case, this is terrible idea, as you are fetching who knows how many records from database, and maybe the user will not work on all of them (depending on the number of records it will not, for sure).

So, it's always best to fetch data only for what one will work on.

Cheers,
Eduardo Jauch