Backendless Support
 
Answered

Add New Object with a Exist Object inside

Hi all,

i have this objects Rooms and Reservations whit a relationship(Reservations have a Room field inside)

When i want to save a new Reservation, the room field is a exist object, then i try with this call:

  1. {
  2. "dateCheckIn": "02/02/2018",
  3. "dateCheckOut": "02/02/2018",
  4. "nameReservation": "tizio",
  5. "room": {
  6. "objectId":"A686A91D-F6F4-1C8B-FF19-5EDA53257000",
  7. "___class":"Rooms"
  8. }
  9. }

The object Reservation save successfully, but the filed room remain empty.

The service's code is the seguent:

  1. /**
  2. * @param {Reservations} reservation
  3. * @returns {Promise.<void>}
  4. */
  5. addReservation(reservation) {
  6. return Backendless.Data.of(Reservations).save(reservation);
  7. }

What i wrong?

thank

GF

Best Answer
photo

you have to wrap "room" into Array

  1. Backendless.Data.of( Reservations ).setRelation(reservationSaved,"room", [room] )

Leave a Comment

Comments (23)

photo
1

Reservations is a class, do you have also a field for the objectId?

photo
1

yes, Reservation have the field room (see 'schema_reservation.png' in the my response of Sergey Kukurudzyak)

photo
photo
1

You have to use relations api to tie objects https://backendless.com/docs/js/doc.html#data_relations_api_set_add_js

photo
1

i have add the relation between Rooms and Reservations (see schema_reservation.png)

My problem is i want to use the service and when i call "addReservation(reservation)" method how should pass the room objectId?

Thank

GF

photo
photo
1

  1. let reservation = ...// save reservation
  2. let rooms = ...// save rooms
  3. Backendless.Data.of( "Reservation" ).setRelation(
  4. reservation,
  5. "room",
  6. rooms )
  7. .then( function( count ) {
  8. //count is a number of created relations
  9. })
  10. .catch( function( error ) {
  11. });

photo
1

sorry, maybe i explained myself wrong.

From my app i call the api of the service i created, then when i want to add a reservation, i call (for example):

  1. https://api.backendless.com/XXXXXXXXX/XXXXXXXXXX/services/Service/Reservation

with a body (for example):

  1. {
  2. "dateCheckIn": "02/02/2018",
  3. "dateCheckOut": "02/02/2018",
  4. "nameReservation": "alador",
  5. "room": {
  6. "objectId":"A686A91D-F6F4-1C8B-FF19-5EDA53257000",
  7. "___class":"Rooms"
  8. }
  9. }

Then, i don't need to save a room, because the room already exists (so i already have the objectId).

Finally, my questions are:

1) How should the body of the call be?

2) How do i write the "reservation" method of the service?

3) The relation is present in the schema, do you still have to set up the relation every time?

Thank

GF

photo
photo
1

1) as this is your service you are responsible to provide correct body, so I cannot tell what the body should be

2) what does this method should do? if create relation then

  1. Backendless.Data.of( "Reservation" ).setRelation(
  2. reservation,
  3. "room",
  4. rooms )
  5. .then( function( count ) {
  6. //count is a number of created relations
  7. })
  8. .catch( function( error ) {
  9. });

where reservation is Reservation object with contains not empty "objectId" property,

rooms array wich cotains Rooms objects which contains not empty "objectIds"

3) you have to call setRelation or addRelation method every time you want to create relation.

photo
1

Perfect, thank for the response.

I have tested whit this method in the 'Api Service' but i receive this error:

400 - Invalid value for the "parent" argument. The argument is required and must contain only string or object values.

What did i wrong?

this is the service's method:

  1. /**
  2. *
  3. *
  4. * @param {Reservations} reservation
  5. * @param {Rooms} room
  6. * @returns {Promise.<void>}
  7. */
  8. addReservation(reservation, room) {
  9. let reservationSaved = Backendless.Persistence.of(Reservations).save(reservation);
  10. return Backendless.Data.of( Reservations ).setRelation(reservationSaved,"room", room );
  11. }
  12. and this the call's body :
  13. {
  14. "reservation": {
  15. "dateCheckIn": "02/02/2018",
  16. "dateCheckOut": "02/02/2018",
  17. "nameReservation": "alador",
  18. "fromFacebook": false,
  19. "fromGroupon": false,
  20. "note": "string",
  21. "totalPrice": "string"
  22. },
  23. "room": {
  24. "objectId":"A686A91D-F6F4-1C8B-FF19-5EDA53257000",
  25. "___class":"Rooms"
  26. }
  27. }

thank

GF

photo
photo
1

you can not use a synchronous methods in business logic. your code should be:

  1. addReservation(reservation, room) {
  2. return Backendless.Persistence.of(Reservations).save(reservation)
  3. .then( function( savedObject ) {
  4. return Backendless.Data.of( Reservations ).setRelation(reservationSaved,"room", room )
  5. .then( function( savedObject ) {
  6. })
  7. .catch( function( error ) {
  8. });
  9. })
  10. .catch( function( error ) {
  11. });
  12. }

photo
1

also room should be an array, for example:

  1. "room": [{
  2. "objectId":"A686A91D-F6F4-1C8B-FF19-5EDA53257000",
  3. "___class":"Rooms"
  4. }]

photo
1

thanks for the response Sergey,

i used your code and when i test the service the response is ok (200) and save the reservation object in db, but the field room is empty.

What did i wrong?

photo
1

Hi jempis

you need to wrap "room" into Array

  1. Backendless.Data.of( Reservations ).setRelation(reservationSaved,"room", [room] )

photo
1

Thank Upirov e Sergey,

now insert the room too.

i add the '[]' in the wrong place.

Thank

photo
photo
1

please attach js file with a service to check it

photo
1

this is service file:

  1. /*Created on 01/05/2018 09:57:34.*/
  2. 'use strict';
  3. const Reservations = require('../models/reservations');
  4. class ReservationsService {
  5. /**
  6. *
  7. *
  8. * @param {Reservations} reservation
  9. * @param {Rooms} room
  10. * @returns {Promise.<void>}
  11. */
  12. addReservation(reservation, room) {
  13. return Backendless.Persistence.of(Reservations).save(reservation)
  14. .then( function( savedObject ) {
  15. return Backendless.Data.of( Reservations ).setRelation(savedObject,"room", room );
  16. })
  17. .catch( function( error ) {
  18. return error;
  19. });
  20. }
  21. }
  22. Backendless.ServerCode.addService(AladorReservationsService);

and this is the Reservation model:

  1. /*Created on 01/05/2018 10:24:50.*/
  2. 'use strict';
  3. /**
  4. * @property {DateTime} dateCheckIn
  5. * @property {DateTime} dateCheckOut
  6. * @property {String} nameReservation
  7. * @property {Rooms} room
  8. */
  9. class Reservations extends Backendless.ServerCode.PersistenceItem {
  10. }
  11. module.exports = Backendless.ServerCode.addType(Reservations);

photo
photo
1

what is your application id?

photo
1

BBE10BDF-E359-D7E9-FFCD-FFA513E2C300

photo
photo
1

you have to wrap "room" into Array

  1. Backendless.Data.of( Reservations ).setRelation(reservationSaved,"room", [room] )

photo
1

Perfect,

thank

photo
photo
1

Sorry is i re open this topic, but not found the solution in the forum and in the doc.

if I want to retrieve a reservation with specific date (checkin and checkout) with a specific room??

I have tested with this query:

  1. var whereClause = "dateCheckIn at or after "+ reservation.dateCheckIn + " and dateCheckIn at or before "+ reservation.dateCheckOut;
  2. whereClause = whereClause + " AND ";
  3. whereClause = whereClause + "room.objectId ="+room.objectId;
  4. return Backendless.Data.of( Reservations ).find( queryBuilder )

But return this error:

  1. 400 - Service invocation failed: ExceptionClass:"RuntimeException" {Msg:"com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [map type; class java.util.HashMap, [simple type, class java.lang.Object] -> [simple type, class java.lang.Object]] from String value ('reservation'); no single-String constructor/factory method at [Source: N/A; line: -1, column: -1]", Cause:"Can not instantiate value of type [map type; class java.util.HashMap, [simple type, class java.lang.Object] -> [simple type, class java.lang.Object]] from String value ('reservation'); no single-String constructor/factory method at [Source: N/A; line: -1, column: -1]"} (14004)

Can you help me?

photo
1

Hi jempis

Could you please provide your AppId and completed WhereClause string

Regards, Vlad

photo
1

my AppId is :

BBE10BDF-E359-D7E9-FFCD-FFA513E2C300

complete Where clause is:

"dateCheckIn at or after 1521500400000 and dateCheckIn at or before 1522274400000 AND room.objectId = 952B05ED-63B6-CEB9-FF8E-C501AFB7EC00"

thank

jempis

photo
1

wrap objectId into single quotes

"dateCheckIn at or after 1521500400000 and dateCheckIn at or before 1522274400000 AND room.objectId = '952B05ED-63B6-CEB9-FF8E-C501AFB7EC00'"

photo