Fetching the asset ID in JS API batching requests


(Lewis) #1

v6.58.0

Hi,

I’m trying to use the JS API with the createFileAsset and updateFileAssetContents operations. There also appears to be a dependency - acquireLock, which I’ve included in my batch request.

According to the docs, I should be able to retrieve the asset id from the createFileAsset operation, and use it in the subsequent acquireLock and updateFileAssetContents operations to udpate the file asset that was created.

Unfortunately, not matter which way I try to combine the %results_0_param% keyword, I keep getting the following error (highlighted in yellow):

I’ve tried a whole load of different combinations, following the docs:

  1. %" + "Results_0_id" + "%
  2. %" + "results_0_id" + "%
  3. %" + "results_0_0_id" + "%
  4. %" + "Results_0_0_id" + "%
  5. “%Results_0_id%”
  6. “%Results_0_0%”
  7. “%results_0_id%”
  8. “%results_0_0%”
  9. “%results_0_0_id%”

Kinda predictably, the ones with capital ‘R’ don’t get replaced, and instead cause the error property in the response to return ’%Results_0_0_id% is not a valid URL’ instead for example.

I’m assuming the first 0 refers to the index of the operation in the batchRequest setup - 0 for the output of the first function, 1 for the output of the second, and so on. In addition, the second 0 (it it’s used), designates the location of the property in the call’s response. The createFileAsset operation outputs the following on success:

… where the bits in yellow are the asset ids. Because the createFileAsset’s response doesn’t explicitly contain ‘id’ property, the _0_id% alternatives above would appear to be irrelevant. I thought perhaps it would be the index within the response in that case, so I tried _0_0% but that didn’t return anything either.

Here’s the final batchRequest before I left off:

js_api.batchRequest({
   "functions":{
		"0":{
			"function":"createFileAsset",
			"args":{
				"parentID":"X",
				"type_code":"File",
				"friendly_name":"reminder33.ics",
				"link_type":"SQ_LINK_TYPE_1",
				"link_value":"link value"
			},
			"blocking":1
		},
		"1":{
			"function":"acquireLock",
			"args":{
				"asset_id":"%results_0_0_0%",
				"screen_name":"",
				"dependants_only":0,
				"force_acquire":1
			},
			"blocking":1
		},
		"2":{
			"function":"updateFileAssetContents",
			"args":{
				"asset_id":"%results_0_0_0%",
				"content":"aGVsbG8sIHdvcmxk",  // "Hello, world"
			}
		}
   },
   "dataCallback":printObject
}); 

Any ideas?


(Lewis) #2

I’ve also noticed a discrepancy between the two versions of the docs:

Also, there’s difference in the capitalisation - '%r … ’ in the older docs, ‘%R …’ in the v6.X docs.


#3

The problem is that the createFileAsset function returns an object that isn’t useful in conjunction with the batchRequest results keyword. It requires you know the property name to access the value, and the property name is the newly created, unknown, asset id.

eg createFileAsset
{ “1234” : “New File Asset (#1234) ‘filename.ext’ of type_code ‘File’ created successfully” }

whereas createAsset returns
{ “name” : “Test”, “id” : 1234, “link_id” : 5678 }
results_0_id => 1234

and no unfortunately you can’t just use createAsset to create file assets.

JohnGill offers a solution here

Otherwise you can abandon batchRequest and chain callbacks. This is more effort (requires more manual error checking) but allows you to extract the created asset id.
eg

js_api.createFileAsset({
            "parentID":1234,
            "type_code":"file",
            "friendly_name":"filename.ext",
            "dataCallback": acquireFileAssetLocks
})

...
acquireFileAssetLocks: function(o) {
    js_api.acquireLock({
        "asset_id":Object.keys(o)[0],
        "dataCallback": uploadFile
    });
}
...

(This could probably be fixed by Squiz while mostly retaining backwards compatibility by amending the createFileAsset return object with additional properties:)
{ “1234” : “New File Asset (#1234) ‘filename.ext’ of type_code ‘File’ created successfully”, “name” : “filename.ext”, “id” : 1234, “link_id” : 5678 }


(Lewis) #4

Thanks for your reply, @bkelly.

That’s what I thought - the createFileAsset operation’s response doesn’t include an ‘id’, but I thought it was something I was missing.

Would be great if there could be this consistency between responses, so we can hook into the responses easily.

Your idea of Object.keys(o)[0] above was along the lines of something I was actually exploring before I discovered the bulk request, down the bottom of the docs. I’ll revisit this in the meantime, as seems the only solution when using the createFileAsset operation at present.


(Iain Simmons) #5

It’s a long shot, but you could try %response_0^array_keys^index:0% or perhaps %response_0^json_decode^array_keys^index:0%, which would be similar to the Object.keys


(Lewis) #6

@bkelly - I’ve gone back over this and tried the idea of essentially chaining the calls together, but hit the same problem - Object.keys(o)[0] isn’t able to fetch anything from, for example acquireLocks as once again, it doesn’t return something I can latch on to - i.e. there’s no ‘id’ (or similar) property.


(Lewis) #7

Hi @isimmons. Thanks for your reply.

I’ll check this out. Have you had any success with it, given the 3 original operations I’m trying to run?


(Iain Simmons) #8

Hi @lewis,

No, I’ve not tried it myself, which is why I said it’s a long shot. I haven’t used the JavaScript API in a very long time.

You might have more luck with the Asset Management API and its createAsset endpoint, if that is enabled in your system.

Otherwise, I believe @bkelly meant to split out the createFileAsset call so it is not part of the batch, and instead in the success callback, get the entire result JSON, get the key in that object since it will be the asset ID, and then store it in an outside variable and use for both of the other subsequent calls.

Cheers,
iain