batchRequest and keywords


(Anewport) #1

So I've been playing around with the JS API and trying to utilise the batchRequest operation to use the response from one function as a parameter to another. Basically I'm trying to create a few assets (from a CSV and Asset Listing Page) and apply metadata to each asset, then repeat for the length of the list (or array which is what the Asset Listing prints out).

 

Here is the code I'm using:

function createResourcesBatch(){
  //loop through array to create each asset
  for (var i=0; i < 2; i++){
    js_api.batchRequest({
       "functions":{
          "0":{
            "function":"createAsset",
            "args":{
              "parent_id":409664,
              "type_code":"link",
              "asset_name":data_array[i][0],
              "link_type":1,
            },
             "blocking":1
          },
          "1":{
            "function":"setAttribute",
            "args":{
              "asset_id":"%results_0_1_id%",
              "attr_name":"link_url",
              "attr_val":data_array[i][3]
            }
          },
          "2":{
            "function":"setMetadataAllFields",
            "args":{
              "asset_id":%results_0_1_id%,
              "field_info":{
                "409760":data_array[i][1],
                "409765":data_array[i][2]
              }
            }
          }
       },
       "dataCallback":printObject
    });
  }
}

 

Note: data_array is the array of data printed out by the asset listing and is defined above this function in the code. Function printObject is taken directly from the Squiz Manuals while testing. Probably won't continue to use a for loop in production but this is fine while I am testing around 5-10 assets at a time.

 

I've got everything else lined up such as the API key, JS API file reference, JS API Details screen, but the issue to me is around using the response from one section and passing it to the other since it uses keywords (not sure if mine are correct) and since these are evaluated on page load, this will not work on a loaded page. Doing a quick test with the sample code provided from the manuals at http://manuals.matrix.squizsuite.net/web-services/chapters/javascript-api#Batching-Requests under the heading "Request (Enhanced)" doesn't work either - yes, I've updated the default asset numbers in the example.

 

Edit: Matrix v4.10.2


JS API batch keyword
(Ashish Karelia) #2

Hi,

When you are using the example from the manuals directly, is there any error coming up on JS side? Have you tried using the example via a Developers Tool like Firebug? That will hopefully give you more details as to what might be going wrong.

 

Having a quick look at the function call you posted I can't see anything wrong but since you are not able to execute the example function call too, it seems like the problem is somewhere else.

 

Ash


(Anewport) #3

Using the exact example from the manuals with my own asset id I get an error. Code and response below. Using Chrome Dev Tools.

var options = new Array();
options['key'] = '5640881591';
var js_api = new Squiz_Matrix_API(options);

js_api.batchRequest({
“functions”:{
“0”:{
“function”:“getChildren”,
“args”:{
“asset_id”:“409663”,
“levels”:1,
“type_codes”:“page_standard”,
“get_attributes”:0
},
“blocking”:1
},
“1”:{
“function”:“setAttribute”,
“args”:{
“asset_id”:"%results_0_0_id%",
“attr_name”:“short_name”,
“attr_val”:“new short name”
}
}
},
“dataCallback”:function(data){console.log(data);}
});

 

Note: when I inspect the code on the loaded page the asset_id for setAttribute appears as "asset_id":"" which is where I think the problem lies.

Response:

Object {error: "You must enter a valid asset id or URL"} 

Doing more testing with the example code, if I only call getChildren then I get the desired response:

[Array[1]]
    0: Array[1]
        0: Object
            //here are all the asset attributes showing correctly

 

So from all this it looks like the first part is working since it is fine by itself and the "blocking" property never gets in the way but rather that the asset_id value for setAttribute becomes an empty string when the page initially loads. Maybe I'm missing something?


(Ashish Karelia) #4

Have you had a look at batchRequest and %results_0_*% syntax forum topic and the resulting bug #6001 createLink fails when using %results_0_id% in batchRequest ?

 

Correct me if I have got it wrong but it seems to me like similar issue.


(Ashish Karelia) #5

Actually my bad. The issue/bug I was referring to was #5945 Inconsistency witht he parameter needs to be passed to (advanced) JS API functions

The patch was release with Matrix version  4.10.5.

 

Ash


(Mpettitt) #6

You might find the following useful - I put it together for internal use and gives some more details on what is returned and expected by the various functions. (I would have attached as Word, but I'm not permitted to upload that type of file...)

 

Asset Objects

 

These are returned from lots of different functions, but generally look the same.


 

  • created: timestamp of the parent asset creation
    time
  • created_userid: asset id of the user who created
    the parent asset
  • created_username: username of the user who
    created the parent asset
  • data_path: system path to the filesystem
    location where the parent asset is stored *POTENTIAL SECURITY RISK*
  • icon_path: web path to the icon used for this type
    of asset
  • id: asset id of the parent asset
  • is_dependant: whether the parent asset is
    dependant to the child. Can be null. Note typo in name
  • is_exclusive: whether the parent asset is
    exclusive to the child. Can be null
  • link_id: the id of the link between the parent
    and child assets. Can be null
  • link_type: type of link, in numeric format. Can
    be null
  • link_value: link value, if set
  • locked: whether this link is locked, to prevent
    it being moved to trash
  • maximum_perm_on_asset: ???
  • name: asset name attribute for parent asset
  • published: timestamp of publication time for
    parent asset
  • published_userid: asset id of the user who last
    published the parent asset
  • published_username: username of the user who
    last published the parent asset
  • short_name: asset short name attribute
  • sort_order: ???
  • status: status of the parent asset, in text form
  • status_changed: timestamp of the last time that
    the parent’s status was changed
  • status_changed_userid: asset id of the user who
    last changed the parent asset’s status
  • status_changed_username: username of the user
    who last changed the parent asset’s status
  • type: readable form of the parent asset type
  • type_code: code form of the parent type
  • updated: timestamp of the last update of the
    parent asset

 

They may also have other attributes, depending on the assets
requested, or the function which returns them:


 

  • getChildren():
  • direct_dependant_children: number of child
    assets of the returned child which are dependant. Note typo in name
  • direct_non_dependant_children: number of child
    assets of the returned child which are not dependant. Note typo in name
  • direct_notice_linked_children: number of notice
    links where the parent of the link is the returned child (e.g. thumbnails)
  • calendar_event_single:
  • description: the event description field
  • end_date: ISO format date string
  • start_date: ISO format date string
  • news_item:
  • body: news item body text
  • contact_name: news item contact name attribute
  • contact_phone: news item contact phone attribute
  • show_body: whether the body should be shown when
    the news item is displayed
  • show_contact_name: whether the contact name
    should be shown when the news item is displayed
  • show_contact_phone: whether the contact phone
    number should be shown
  • show_headline: whether the headline should be
    shown
  • show_summary: whether the summary should be
    shown
  • url_suffix: ???


  createAsset()

Parameters:

  • parent_id: required, should be the asset id of
    the asset the new asset will be created under. This must be in one of the
    allowed create folders set in the JS API asset, and must be of a type that
    accepts children of the type being created
  • type_code: required, the type code as shown in
    the asset tree. Must be an allowed type permitted in the JS API asset
  • asset_name: required, the long name of the
    asset. Even required for asset types that don’t use it, such as users
  • link_type: required, the required link type,
    where 1 is Type 1, 2 is Type 2, 4 is Type 3 and 8 is Notice
  • link_value: required, can be empty, but must be
    supplied.
  • sort_order: set to -1 for “at the bottom of the
    child assets”. Seems to get confused if you give it a higher number than there
    are assets in the parent, rather than just putting the new asset at the bottom
  • is_dependent: set it to 0
  • is_exclusive: set to 0
  • extra_attributes: technically optional, but
    required for certain asset types
  • attributes: technically optional, but required
    for certain asset types. In particular:
  • Single Calendar Events: you must supply the
    start_date and end_date parameters
  • Users: you must supply the username and
    password, in that order
  • dataCallback: takes either a function, or a
    reference to a function. The function referenced will be passed an object of
    the return from the call, which can be manipulated. Errors and standard
    responses are returned in the same object


  getChildren()

Parameters:

  • asset_id: the asset to get the children of
  • levels: the number of levels of depth to get,
    where direct children are level 1
  • type_codes: array of types from the asset tree
  • link_types: array of link types, in the form
    SQ_LINK_TYPE_1, SQ_LINK_TYPE_2, SQ_LINK_TYPE_3, SQ_LINK_TYPE_NOTICE
  • link_values: array of possible link values for the
    children. Set to empty array for all children
  • get_attributes: whether to get the attributes of
    the children or not, where 0 is false, 1 is true
  • dataCallback: return function


  getParents()


 

Parameters:

  • asset_id: asset to find the parents of
  • levels: number of levels to get, where immediate
    parents are 1
  • type_codes: array of asset types to get – if you
    only want a single type, still needs to be an array
  • link_types: array of link types to get, in
    SQ_LINK_TYPE_ format
  • dataCallback: receives an array of asset objects,
    each of which contains:
  • updated_userid: asset id of the user who last
    updated the parent asset
  • updated_username: username of the user who last
    updated the parent asset
  • web_path: shortest web path to the parent asset


  createLink()

Parameters:

  • parent_id: id of the parent asset for the new
    link
  • child_id: id of the asset to be linked into the
    parent
  • link_type: type of new link, in numeric format
  • link_value: new link value for the new link
  • sort_order: as above
  • is_dependant: set to 0
  • is_exclusive: set to 0 – by definition, any
    asset which you’re creating a link to with createLink exists somewhere else, so
    it’s not exclusive. Causes errors if you set to 1
  • dataCallback: receives a “link created” message
    with the link id, or an error


  batchRequest()

 

Differences between batched and standard requests:

  • createAsset: takes “id” instead of “parent_id”
  • createFileAsset: takes “id” instead of
    “parent_id”
  • createLink: takes “id” instead of “child_id”
  • removeLink: takes “id” instead of “child_id”
  • getLinkId: takes “id” instead of “child_id”

(Anewport) #7

Have you had a look at batchRequest and %results_0_*% syntax forum topic and the resulting bug #6001 createLink fails when using %results_0_id% in batchRequest ?  
Correct me if I have got it wrong but it seems to me like similar issue.

I tried the other forum topic code and all I could reproduce was the asset being created; setAttribute and setMetadata did not work for me. I know I have to be missing something really simple if working code from another user doesn't work for me. I don't think I understand how the %response_0_*% keyword works fully since it doesn't make sense to me that a keyword can still function after a page has been loaded. My JavaScript (from the first post) loads up in the browser as the following:

         {
         "function":"setAttribute",
         "args":{
            "asset_id":"",
            "attr_name":"short_name",
            "attr_val":"new short name"
         }

In the code from the administration interface, asset_id has the value %results_0_0_id% but since this is evaluated on page load, it becomes nothing - which makes sense as there is nothing stored in that keyword as the script has not yet run.
 

You might find the following useful

Wow thanks Matthew, that's a pretty useful list.


(Ashish Karelia) #8

Hi,

It seems like Matrix is trying to evaluate the %results_0_0_id% keyword on page load. Which would be very weird.

Can you try replacing the % with &#37; and see if on page load the keyword now appears correctly?
As long as the keyword is printed correctly, JS API should b able to work out the value.

If this fails, can you check and paste us the exact error as it appears in the error.log.

 

 

 

EDIT: Actually I tried and the replacement of the % with its Ascii equavilent isn't working too. But what i found to be working is :

 

 

"asset_id":"%" + "results_0_0_id" + "%"

 

Although this should be only used as a work around as ideally Matrix should not have tried to replace the %results_0_*% based keywords. May be that needs to be looked into. Feel free to go ahead and file a bug report for it :)

 

Ash


(Anewport) #9
"asset_id":"%" + "results_0_0_id" + "%"

 

Thanks Ash! Using the above code worked perfectly. I didn't think the system should be parsing the %results_0_*% keywords but this is a great work around for now.

 

Filed bug report http://bugs.matrix.squiz.net/view_bug.php?bug_id=6147


(Mitch Kerry) #10

Hi
I’m having a similar problem…only the solution here is not working.
Trying to batch a createAsset and a setMetadataAllFields call.
I’m getting {error: “You must enter a valid asset id or URL”, errorCode: “badRequest”} on the second call.

function matrixCreate (a, b, c, d, e,  f, g) 

js_api.batchRequest({
  "functions":{
      "0":{
         "function":"createAsset",
         "args":{
            "parent_id":XXXXXX,
             "type_code":"user",
             "asset_name": b + c,
             "link_type":"SQ_LINK_TYPE_1",
             "link_value":"link value",
             "sort_order":1,
             "is_dependant":0,
             "is_exclusive":0,
             "extra_attributes":1,
             "attributes":"name=" + a + "&email=" + e + "&first_name=" + b + "&last_name=" + c + "&username=" + a + "&password=" + f
          },
         "blocking":1
      },
      "1":{
         "function":"setMetadataAllFields",
         "asset_id":"%" + "results_0_0_id" + "%",
         "field_info":{
              "251070": d,
              "251071": a,
              "251072": g
          },
      }
  },
  "dataCallback": printObject
}); 

}

The create works fine but the second function does not get the asset_id.

Appreciate any help