amazon-archives / aws-sdk-react-native

AWS SDK for React Native (developer preview)
Apache License 2.0
631 stars 68 forks source link

Unable to successfully call AWSDynamoDB.Query #7

Open MadisonBlake opened 7 years ago

MadisonBlake commented 7 years ago

I am calling AWSDynamoDB.Query with the following options:

{"TableName":"MyTable", "KeyConditionExpression":"ID=:id","ExpressionAttributeValues":{":id":"MyValue"}}

In AWSRNDynamoDBClient.Query the following exception is thrown when creating QueryResult:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 38 path $.ExpressionAttributeValues.

It really seems like my parameters are correct, so I modified AWSRNDynamoDBClient::Query to manually build the request for those given parameters

QueryRequest request;
if(options.hasKey("TableName") && options.hasKey("KeyConditionExpression") && options.hasKey("ExpressionAttributeValues")) {
    request=new QueryRequest();
    request.setTableName(options.getString("TableName"));
    request.setKeyConditionExpression(options.getString("KeyConditionExpression"));

    java.util.Map<String, AttributeValue> expressionAttributeValues = new java.util.HashMap<>();
    ReadableMap expressionAttributeValueMap = options.getMap("ExpressionAttributeValues");
    ReadableMapKeySetIterator expressionAttributeValueMap_itr = expressionAttributeValueMap.keySetIterator();
    while (expressionAttributeValueMap_itr.hasNextKey()) {
        String key = expressionAttributeValueMap_itr.nextKey();
        expressionAttributeValues.put(key, new AttributeValue(expressionAttributeValueMap.getString(key)));
    }

    request.setExpressionAttributeValues(expressionAttributeValues);
}
else
    request = gson.fromJson(new JSONObject(AWSRNClientMarshaller.readableMapToMap(options)).toString(), QueryRequest.class);

With that code, the request is correctly built and properly queries the DynamoDB. Obviously that code isn't production quality, but I believe it shows that the incoming options are correctly formatted?

markbiddlecom commented 7 years ago

I think the problem is in your ExpressionAttributeValues map, which should look more like:

"ExpressionAttributeValues":{":id",{"S":"MyValue"}}"

MadisonBlake commented 7 years ago

In accordance to @markbiddlecom suggestion the following command works with non-modified package:

AWSDynamoDB.Query({"TableName":"MyTable", "KeyConditionExpression":"ID=:id","ExpressionAttributeValues":{":id":{"S":"MyValue"}}})
    .then((response) => {
        console.log(response);
        }
    });

Is the need for {"S":"MyValue"} documented anywhere? I was largely basing Query's options parameter based on params varable for the same function in Node.js.

kanerogers commented 7 years ago

@MadisonBlake It's quite unintuitive , but yes it's documented over here. This has stung me many times.