Skip to content

Commit e6ab6c3

Browse files
authored
Add context to Parse.Object.save (#1150)
* added failing test * added transmitting context in request body - context is transmitted as `_context` property in REST request - given that a leading underscore `_` marks a reserved property * added docs
1 parent 7cf413e commit e6ab6c3

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

src/ParseObject.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ type SaveParams = {
5656
};
5757

5858
type SaveOptions = FullOptions & {
59-
cascadeSave?: boolean
59+
cascadeSave?: boolean;
60+
context?: AttributeMap;
6061
}
6162

6263
// Mapping of class names to constructors, so we can populate objects from the
@@ -1179,6 +1180,7 @@ class ParseObject {
11791180
* <li>sessionToken: A valid session token, used for making a request on
11801181
* behalf of a specific user.
11811182
* <li>cascadeSave: If `false`, nested objects will not be saved (default is `true`).
1183+
* <li>context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers.
11821184
* </ul>
11831185
* </li>
11841186
* </ul>
@@ -1192,6 +1194,7 @@ class ParseObject {
11921194
* <li>sessionToken: A valid session token, used for making a request on
11931195
* behalf of a specific user.
11941196
* <li>cascadeSave: If `false`, nested objects will not be saved (default is `true`).
1197+
* <li>context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers.
11951198
* </ul>
11961199
*
11971200
* @return {Promise} A promise that is fulfilled when the save
@@ -1251,6 +1254,9 @@ class ParseObject {
12511254
if (options.hasOwnProperty('installationId') && typeof options.installationId === 'string') {
12521255
saveOptions.installationId = options.installationId;
12531256
}
1257+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1258+
saveOptions.context = options.context;
1259+
}
12541260
const controller = CoreManager.getObjectController();
12551261
const unsaved = options.cascadeSave !== false ? unsavedChildren(this) : null;
12561262
return controller.save(unsaved, saveOptions).then(() => {

src/RESTController.js

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type RequestOptions = {
2121
batchSize?: number;
2222
include?: any;
2323
progress?: any;
24+
context?: any;
2425
};
2526

2627
export type FullOptions = {
@@ -222,6 +223,13 @@ const RESTController = {
222223
}
223224
}
224225

226+
// Add context
227+
const context = options.context;
228+
if (context !== undefined) {
229+
payload._context = context;
230+
delete options.context;
231+
}
232+
225233
if (method !== 'POST') {
226234
payload._method = method;
227235
method = 'POST';

src/__tests__/ParseObject-test.js

+20
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,26 @@ describe('ParseObject', () => {
12191219
});
12201220
});
12211221

1222+
it('accepts context on save', async () => {
1223+
// Mock XHR
1224+
CoreManager.getRESTController()._setXHR(
1225+
mockXHR([{
1226+
status: 200,
1227+
response: { objectId: 'newattributes' }
1228+
}])
1229+
);
1230+
// Spy on REST controller
1231+
const controller = CoreManager.getRESTController();
1232+
jest.spyOn(controller, 'ajax');
1233+
// Save object
1234+
const context = {a: "a"};
1235+
const obj = new ParseObject('Item');
1236+
await obj.save(null, {context});
1237+
// Validate
1238+
const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]);
1239+
expect(jsonBody._context).toEqual(context);
1240+
});
1241+
12221242
it('interpolates delete operations', (done) => {
12231243
CoreManager.getRESTController()._setXHR(
12241244
mockXHR([{

0 commit comments

Comments
 (0)