Jack
Jack

Reputation: 1372

passing json to lambda function within

i'm writing a serverless application and im having trouble when invoking lambda function inside function. Two functions are working as expected separately. when i try to execute function B from function A it gives following error.

Unexpected token u in JSON at position 0

here is my code and i'm sure my payload is not passing to second function, how can i resolve it? Function A

module.exports.create = (event, context, callback) => {
  console.log('inside');
  const timestamp = new Date().getTime();
  console.log(JSON.parse(event.body));
  const data = JSON.parse(event.body);

  var jsonObj = {'user_avatar' : 'data.user_avatar',
                'name' : 'data.name'}
  const params2 = {
  FunctionName: "serverless-rest-api-with-dynamodb-dev-uploadImage",
  InvocationType: "RequestResponse",
  LogType: 'Tail',
  Payload: JSON.stringify(jsonObj)
  };

  lambda.invoke(params2, function (err, data) {
  if (err) {
    console.log('error : ' + err)
    callback(err, null)
  } else if (data) {
    const response = {
      statusCode: 200,
      body: JSON.parse(data.Payload)
    }
    callback(null, response)
  }
})

  const params = {
    TableName: process.env.BANK_TABLE,
    Item: {
      id: uuid.v1(),
      bankName: data.bankName,
      bankUrl: data.bankUrl,
      bankCardUrl: data.bankCardUrl,
      bankLogoID: data.bankLogoID,
      createdAt: timestamp,
      updatedAt: timestamp,
    },
  };

  // write the offers to the database
  dynamoDb.put(params, (error) => {
    // handle potential errors
    if (error) {
      console.error(error);
      callback(null, {
        statusCode: error.statusCode || 501,
        headers: { 'Content-Type': 'text/plain' },
        body: 'Couldn\'t create the offer item.',
      });
      return;
    }
    console.log('setting callback');
    // create a response
    const response = {
      statusCode: 200,
      body: JSON.stringify(params.Item),
    };
    callback(null, response);
  });
};

Function B

module.exports.create = (event, context, callback) => {
  console.log('staring');
    console.log(JSON.parse(event.body));
     let encodedImage =JSON.parse(event.body).user_avatar;
     let decodedImage = Buffer.from(encodedImage, 'base64');
     var filePath = "avatars/" + JSON.parse(event.body).name + ".jpg"
     var params = {
       "Body": decodedImage,
       "Bucket": "imageuploads",
       "Key": filePath
    };
    s3.upload(params, function(err, data){
       if(err) {
           callback(err, null);
       } else {
           let response = {
        "statusCode": 200,
        "headers": {
            "my_header": "my_value"
        },
        "body": JSON.stringify(data),
        "isBase64Encoded": false
    };
           callback(null, response);
    }
    });

};

Upvotes: 0

Views: 6286

Answers (4)

Pau A.
Pau A.

Reputation: 11

The error you get:

Unexpected token u in JSON at position 0

is usually due to a malformed JSON. Following the JSON Syntax from W3Schools:

JSON names require double quotes. JavaScript names don't.

so your jsonObj should be:

var jsonObj = {"user_avatar" : data.user_avatar,
                "name" : data.name}

Also, note that data.user_avatar and data.name are variables and they shouldn't have quotes.

Upvotes: 1

IftekharDani
IftekharDani

Reputation: 3729

You have to change request Body.

const data = JSON.parse(event.body);

var jsonObj = {
  body: { //add body
    'user_avatar': data.user_avatar, //remove single quotes
    'name': data.name //remove single quotes
  }
}
const params2 = {
  FunctionName: "serverless-rest-api-with-dynamodb-dev-uploadImage",
  InvocationType: "RequestResponse",
  LogType: 'Tail',
  Payload: JSON.stringify(jsonObj)
};

lambda.invoke(params2, function(err, data) {
  if (err) {
    console.log("error : " + err);
    callback(err, null);
  } else if (data) {
    const response = {
      statusCode: 200,
      body: JSON.parse(data.Payload)
    };
    callback(null, response);
  }
});

Upvotes: 0

Cleriston
Cleriston

Reputation: 770

If you are invoking your lambda function internally (for an unit test, for example), you should make sure you send it as a json http format.

create({body: JSON.stringify(myBodyObject)}, null, callBack)

Upvotes: 0

thomasmichaelwallace
thomasmichaelwallace

Reputation: 8474

The problem is in the Payload you're sending from A to B.

(Note that JSON.parse(undefined) is almost always the culprit behind SyntaxError: Unexpected token u in JSON at position 0).

Function B, Line 3 says: console.log(JSON.parse(event.body));

However, your payload from A (A, Line 12) is: {'user_avatar' : 'data.user_avatar', 'name' : 'data.name'}.

This means that event = JSON.stringify({'user_avatar' : 'data.user_avatar', 'name' : 'data.name'}) and event.body === undefined, which is why when you try and JSON.parse(event.body) you get your error.

To make this work you need to change A line 7 to:

var jsonObj = { body: { user_avatar: 'data.user_avatar', name: 'data.name' } };

I suspect it's working when you invoke separately because you're either invoking using API Gateway (which has an event shape of { body: ...data }, or your test body in the console has something similar.)

Upvotes: 0

Related Questions