Skip to content
This repository has been archived by the owner on Oct 23, 2020. It is now read-only.

Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 - When posting new Statement #32

Open
venkatapathy opened this issue Jun 4, 2017 · 7 comments

Comments

@venkatapathy
Copy link

Guys,

I am trying to use jxapi with OpenLrs- which is an open source LRS written in Java. So when I try to Post a single statement (or multiple statements for that matter), it returns Json response as Jsonarray. For eg:
For a post statement below:

{
  "actor": {
    "name": "Sally Glider",
    "mbox": "mailto:[email protected]"
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/experienced",
    "display": { "en-US": "experienced" }
  },
  "object": {
    "id": "http://example.com/activities/solo-hang-gliding",
    "definition": {
      "name": { "en-US": "Solo Hang Gliding" }
    }
  }
}

OpenLrs' response is:

[
  "c250f7a5-859b-4080-a8cb-0972fa76b25d"
]

Now this throws an error:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2

in the class-StatementClient in the function:

public String postStatement(Statement statement)

at line:
JsonArray jsonResult = gson.fromJson(result, JsonArray.class);

I even tried to convert the response to Jsonarray at the source- Openlrs before returning, but it still throws the same error.

Could someone tell me what's the expected response? In the specification, there is no hint given except that it says the POST should return an array of id, which as I see it, the Openlrs does follow suit? Could anyone please help me? Thanks

@rneatrour
Copy link
Contributor

The jxapi postStatement method will return a single ID, and it's a string.

String publishedId = statementClient.postStatement(statement);

The postStatements method will return an ID for each statement in an ArrayList.

ArrayList<String> publishedIds = statementClient.postStatements(statements);

@venkatapathy
Copy link
Author

Hi,
Thanks for the reply. I still have a doubt on this. I agree that:

String publishedId = statementClient.postStatement(statement);

returns a single ID which is a string. But, in the code StatementClient.postStatement(statement), you still parse an array of IDs and return the first ID:

JsonArray jsonResult = gson.fromJson(result, JsonArray.class);
return jsonResult.get(0).getAsString();

So basically both statementClient.postStatement(statement) and statementClient.postStatements(statements) expect results with same JSON format from LRS. My question is what is this format should be, because:


[
  "c250f7a5-859b-4080-a8cb-0972fa76b25d"
]

for statementClient.postStatement(statement), throws an exception. For example, could you tell me what should be a return JSON object from the LRS for a statement:

{
  "actor": {
    "name": "Sally Glider",
    "mbox": "mailto:[email protected]"
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/experienced",
    "display": { "en-US": "experienced" }
  },
  "object": {
    "id": "http://example.com/activities/solo-hang-gliding",
    "definition": {
      "name": { "en-US": "Solo Hang Gliding" }
    }
  }
}

Based on that I will change the LRS side response code. Note that the statement is successfully stored in the LRS and the Statement ID is returned. The problem is only in the parsing of the JSON response at line:
JsonArray jsonResult = gson.fromJson(result, JsonArray.class);

Thanks

@ljwolford
Copy link
Contributor

Whenever one or more statements are POSTed, the LRS must return an array of IDs, like you described. So if a single statement is posted, the LRS should return ["c250f7a5-859b-4080-a8cb-0972fa76b25d"]. jXAPI then just parses that result and returns the single ID as a string for usability. Have you tried POSTing to a different LRS to see if the error still occurs?

@venkatapathy
Copy link
Author

Hi,

I tried to POSTed a statement to

https://lrs.adlnet.gov/xAPI/

LRS successfully stored the statement and returned the ID. And the jxApi still threw an JsonSyntaxException as mentioned above.

So guess its a bug?

You can find the following statement at http://adlnet.github.io/xapi-statement-viewer/:

{
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/launched",
    "display": {
      "en-US": "launched"
    }
  },
  "version": "1.0.0",
  "timestamp": "2017-06-05T12:53:27.836827+00:00",
  "object": {
    "id": "https://www.youtube.com/watch?v=tlBbt5niQto",
    "objectType": "Activity"
  },
  "actor": {
    "mbox": "mailto:[email protected]",
    "objectType": "Agent"
  },
  "stored": "2017-06-05T12:53:27.836827+00:00",
  "authority": {
    "mbox": "mailto:[email protected]",
    "name": "xapi-tools",
    "objectType": "Agent"
  },
  "id": "a14600cc-4e39-483b-b040-0aa0ae94f04f"
}

@rneatrour
Copy link
Contributor

This test posts and returns an ID with no exceptions thrown.

StatementClient client = new StatementClient(lrs_uri, username, password);
		
Statement st = new Statement(new Agent("test", mbox), 
				new Verb("http://adlnet.gov/expapi/verbs/launched"), 
				new Activity("https://www.youtube.com/watch?v=tlBbt5niQto"));
		
String publishedId = client.postStatement(st);

It returns d03a76ac-c3e6-4e3d-8354-ce7bc6898489

The statement stored:

{
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/launched"
  },
  "version": "1.0.0",
  "timestamp": "2017-06-05T13:18:12.401968+00:00",
  "object": {
    "id": "https://www.youtube.com/watch?v=tlBbt5niQto",
    "objectType": "Activity"
  },
  "actor": {
    "mbox": "mailto:[email protected]",
    "name": "test",
    "objectType": "Agent"
  },
  "stored": "2017-06-05T13:18:12.401968+00:00",
  "authority": {
    "mbox": "mailto:[email protected]",
    "objectType": "Agent"
  },
  "id": "d03a76ac-c3e6-4e3d-8354-ce7bc6898489"
}

Is there a public link to your LRS for me to test against?

@venkatapathy
Copy link
Author

Originally I had my own local server from compiled from:

https://github.com/Apereo-Learning-Analytics-Initiative/OpenLRS

But I also tested with the ADL's LRS. The following code also throws an exception:

Statement statement = new Statement(new Agent("test", "mailto:[email protected]"), new                Verb("http://adlnet.gov/expapi/verbs/launched"),
				    new Activity("https://www.youtube.com/watch?v=tlBbt5niQto"));

StatementClient client=new StatementClient("https://lrs.adlnet.gov/xapi/", "xapi-tools",
					"xapi-tools");

			// send the statement, if successful store the uuid for future
			// references
			try {
				String publishedId = client.postStatement(statement);
				

		} catch (JsonSyntaxException e) {
			// ignore due to a bug
			System.out.println("Exception while reading the Id!!");
			
		} 

@ruizrube
Copy link

I got the same exception when sending a xAPI statement to a Learning Locker instance. Anyway, the statement is properly saved in the store.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants