Hi,
So finally I got the Tour of Heroes from the Angular(2) tutorial [1] working with BaseX as database backend.
Everything works pretty well except for one thing: When adding a new record, Angular expects the backend (BaseX) to create an unique ID for the record and send it, together with the original, back to the angular-frontend [2].
In BaseX however, it is not possible to retrieve updated data from within the same transaction as the update of the database took place.
The work around is to fetch the updated record outside the updating-transaction by means of a web:redirect to the link that retrieves a record [3].
This work around has two major disadvantages:
1. one can never be a 100% sure that the fetched data is exactly the data as it was stored in the base because updating and fetching are two separate transactions.
2. this only works if the records have a unique set of key fields. This doesn't always have to be the case.
I've reported this situation a while ago and I wouldn't come back on it if the Angular-way of working didn't come up with the same situation.
In my opinion BaseX would even be better equipped as database backend as it is if it was possible to fetch the updated date in the database from within the same transaction as the update took place.
Is this something that could be considered for a future release?
Cheers,
Rob Stapper
PS. I got this far thanks to the suggestions on CORS.
[1] https://angular.io/docs/ts/latest/tutorial
[2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html chapter: "Add a hero".
[3]
declare
%rest:path("/product/save")
%rest:POST("{ $parameterSet}")
%updating
function _:product.save
( $parameterSet as array(*)
)
{
( db:output( web:redirect( "/product/find"
, map{ "code" : $parameterSet(2) }
)
)
, dbx:save( $_:dataBase
, $_:objectType
, trace( $parameterSet(1), "objectID:" )
, product:new( $parameterSet(2)
, $parameterSet(3)
, $parameterSet(4)
)
)
)
Hi Rob,
Good to hear you have solved the CORS problem.
In BaseX however, it is not possible to retrieve updated data from within
the same transaction as the update of the database took place.
I think often this is not so much of a problem as it first appears because you know the data going into the transaction and the current state of the database and can use this data in db:output(), which will only run if the transaction succeeded. For the case of generating ids you might use increment a counter or generate a guid, in either case the computed value can be used in the db:output expression. I wrote a similar sounding project to yours basex-cellar [1] [2] using angular 1, (a slightly scary 5 years ago- it may have suffered some bit rot over the years ). An example of an update, in this case adding a wine to a cellar database is [3]
/Andy [1] https://github.com/apb2006/basex-cellar [2] https://www.slideshare.net/AndyBunce/base-x-usergrouptalk [3] https://github.com/apb2006/basex-cellar/blob/master/src/cellar/api/cellar.xq...
On 7 March 2017 at 19:48, Rob Stapper r.stapper@lijbrandt.nl wrote:
Hi,
So finally I got the Tour of Heroes from the Angular(2) tutorial [1] working with BaseX as database backend.
Everything works pretty well except for one thing: When adding a new record, Angular expects the backend (BaseX) to create an unique ID for the record and send it, together with the original, back to the angular-frontend [2].
In BaseX however, it is not possible to retrieve updated data from within the same transaction as the update of the database took place.
The work around is to fetch the updated record outside the updating-transaction by means of a web:redirect to the link that retrieves a record [3].
This work around has two major disadvantages:
- one can never be a 100% sure that the fetched data is exactly the data
as it was stored in the base because updating and fetching are two separate transactions.
- this only works if the records have a unique set of key fields. This
doesn’t always have to be the case.
I’ve reported this situation a while ago and I wouldn’t come back on it if the Angular-way of working didn’t come up with the same situation.
In my opinion BaseX would even be better equipped as database backend as it is if it was possible to fetch the updated date in the database from within the same transaction as the update took place.
Is this something that could be considered for a future release?
Cheers,
Rob Stapper
PS. I got this far thanks to the suggestions on CORS.
[1] https://angular.io/docs/ts/latest/tutorial
[2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html chapter: “Add a hero”.
[3]
declare
%rest:path("/product/save")
%rest:POST("{ $parameterSet}")
%updating
function _:product.save
( $parameterSet as array(*)
)
{
( db:output( web:redirect( "/product/find" , map{ "code" : $parameterSet(2) } ) ) , dbx:save( $_:dataBase , $_:objectType , trace( $parameterSet(1), "objectID:" ) , product:new( $parameterSet(2) , $parameterSet(3) , $parameterSet(4) ) ) )
Thanks Andy and Wray for your response.
In my case the ID is generated at the backend as part of the transaction. Which I think is the proper place to do in a multi user environment. Fetching this ID within a db:output can only be done if my data has a unique key. This doesn't necessarily always be the case. Agreed; it is a pretty theoretical approach but if it makes theoretically sence.
I could try to get the ID as a result of the transaction, probably need mixedupdates set, and use this whitin a db:output.
cheers Rob
PS. @ Andy, I needed OPTIONS in the REST-interface, which worked ;-) I'll have a look in your wine cellar.
Andy Bunce schreef op 07.03.2017 22:30:
Hi Rob,
Good to hear you have solved the CORS problem.
In BaseX however, it is not possible to retrieve updated data from
within the same transaction as the update of the database took place.
I think often this is not so much of a problem as it first appears because you know the data going into the transaction and the current state of the database and can use this data in db:output(), which will only run if the transaction succeeded. For the case of generating ids you might use increment a counter or generate a guid, in either case the computed value can be used in the db:output expression. I wrote a similar sounding project to yours basex-cellar [1] [2] using angular 1, (a slightly scary 5 years ago- it may have suffered some bit rot over the years ).
An example of an update, in this case adding a wine to a cellar database is [3]
/Andy [1] https://github.com/apb2006/basex-cellar [3] [2] https://www.slideshare.net/AndyBunce/base-x-usergrouptalk [4] [3] https://github.com/apb2006/basex-cellar/blob/master/src/cellar/api/cellar.xq... [5]
On 7 March 2017 at 19:48, Rob Stapper r.stapper@lijbrandt.nl wrote:
Hi,
So finally I got the Tour of Heroes from the Angular(2) tutorial [1] working with BaseX as database backend.
Everything works pretty well except for one thing: When adding a new record, Angular expects the backend (BaseX) to create an unique ID for the record and send it, together with the original, back to the angular-frontend [2].
In BaseX however, it is not possible to retrieve updated data from within the same transaction as the update of the database took place.
The work around is to fetch the updated record outside the updating-transaction by means of a web:redirect to the link that retrieves a record [3].
This work around has two major disadvantages:
- one can never be a 100% sure that the fetched data is exactly the
data as it was stored in the base because updating and fetching are two separate transactions.
- this only works if the records have a unique set of key fields.
This doesn’t always have to be the case.
I’ve reported this situation a while ago and I wouldn’t come back on it if the Angular-way of working didn’t come up with the same situation.
In my opinion BaseX would even be better equipped as database backend as it is if it was possible to fetch the updated date in the database from within the same transaction as the update took place.
Is this something that could be considered for a future release?
Cheers,
Rob Stapper
PS. I got this far thanks to the suggestions on CORS.
[1] https://angular.io/docs/ts/latest/tutorial [1]
[2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html [2] chapter: “Add a hero”.
[3]
declare
%rest:path("/product/save")
%rest:POST("{ $parameterSet}")
%updating
function _:product.save
( $parameterSet as array(*)
)
{
( db:output( web:redirect( "/product/find"
, map{ "code" : $parameterSet(2) }
)
)
, dbx:save( $_:dataBase
, $_:objectType
, trace( $parameterSet(1), "objectID:" )
, product:new( $parameterSet(2)
, $parameterSet(3)
, $parameterSet(4)
)
)
)
Links:
[1] https://angular.io/docs/ts/latest/tutorial [2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html [3] https://github.com/apb2006/basex-cellar [4] https://www.slideshare.net/AndyBunce/base-x-usergrouptalk [5] https://github.com/apb2006/basex-cellar/blob/master/src/cellar/api/cellar.xq...
Hi Rob,
Andy has already given you all relevant links. I am left with one question: What does your dbx:save function do? Is this the function that generates the ID?
Christian
On Wed, Mar 8, 2017 at 9:43 AM, r.stapper@lijbrandt.nl wrote:
Thanks Andy and Wray for your response.
In my case the ID is generated at the backend as part of the transaction. Which I think is the proper place to do in a multi user environment. Fetching this ID within a db:output can only be done if my data has a unique key. This doesn't necessarily always be the case. Agreed; it is a pretty theoretical approach but if it makes theoretically sence.
I could try to get the ID as a result of the transaction, probably need mixedupdates set, and use this whitin a db:output.
cheers Rob
PS. @ Andy, I needed OPTIONS in the REST-interface, which worked ;-) I'll have a look in your wine cellar.
Andy Bunce schreef op 07.03.2017 22:30:
Hi Rob,
Good to hear you have solved the CORS problem.
In BaseX however, it is not possible to retrieve updated data from
within the same transaction as the update of the database took place.
I think often this is not so much of a problem as it first appears because you know the data going into the transaction and the current state of the database and can use this data in db:output(), which will only run if the transaction succeeded. For the case of generating ids you might use increment a counter or generate a guid, in either case the computed value can be used in the db:output expression. I wrote a similar sounding project to yours basex-cellar [1] [2] using angular 1, (a slightly scary 5 years ago- it may have suffered some bit rot over the years ).
An example of an update, in this case adding a wine to a cellar database is [3]
/Andy [1] https://github.com/apb2006/basex-cellar [3] [2] https://www.slideshare.net/AndyBunce/base-x-usergrouptalk [4] [3]
https://github.com/apb2006/basex-cellar/blob/master/src/cellar/api/cellar.xq... [5]
On 7 March 2017 at 19:48, Rob Stapper r.stapper@lijbrandt.nl wrote:
Hi,
So finally I got the Tour of Heroes from the Angular(2) tutorial [1] working with BaseX as database backend.
Everything works pretty well except for one thing: When adding a new record, Angular expects the backend (BaseX) to create an unique ID for the record and send it, together with the original, back to the angular-frontend [2].
In BaseX however, it is not possible to retrieve updated data from within the same transaction as the update of the database took place.
The work around is to fetch the updated record outside the updating-transaction by means of a web:redirect to the link that retrieves a record [3].
This work around has two major disadvantages:
- one can never be a 100% sure that the fetched data is exactly the
data as it was stored in the base because updating and fetching are two separate transactions.
- this only works if the records have a unique set of key fields.
This doesn’t always have to be the case.
I’ve reported this situation a while ago and I wouldn’t come back on it if the Angular-way of working didn’t come up with the same situation.
In my opinion BaseX would even be better equipped as database backend as it is if it was possible to fetch the updated date in the database from within the same transaction as the update took place.
Is this something that could be considered for a future release?
Cheers,
Rob Stapper
PS. I got this far thanks to the suggestions on CORS.
[1] https://angular.io/docs/ts/latest/tutorial [1]
[2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html [2] chapter: “Add a hero”.
[3]
declare
%rest:path("/product/save")
%rest:POST("{ $parameterSet}")
%updating
function _:product.save
( $parameterSet as array(*)
)
{
( db:output( web:redirect( "/product/find"
, map{ "code" : $parameterSet(2) }
)
)
, dbx:save( $_:dataBase
, $_:objectType
, trace( $parameterSet(1), "objectID:" )
, product:new( $parameterSet(2)
, $parameterSet(3)
, $parameterSet(4)
)
)
)
Links:
[1] https://angular.io/docs/ts/latest/tutorial [2] https://angular.io/docs/ts/latest/tutorial/toh-pt6.html [3] https://github.com/apb2006/basex-cellar [4] https://www.slideshare.net/AndyBunce/base-x-usergrouptalk [5]
https://github.com/apb2006/basex-cellar/blob/master/src/cellar/api/cellar.xq...
basex-talk@mailman.uni-konstanz.de