Stripe having trouble extracting the json card id - stripe-payments

With Stripe php I am creating a new source with code below.
then when I show $response_all it looks like good json like:
{id: "card_xxxxxxxxxx", object: "card", address_city: null, address_country: null, address_line1: null, …} etc.......
however when I try to extract just the id only using
$response_id = $response.id;
then the json has a TEXT prefix like
"Stripe\Card JSON: {
"id": "card_xxxxxxxxxx", etc
Q: How Can I extract the Card id without getting the text prefix?
$stripe_customer = $_POST['stripe_customer'];
$stripe = new \Stripe\StripeClient(
'sk_test_xxxxxxxxx'
);
$response = $stripe->customers->createSource(
$stripe_customer,
['source' => $token]
);
$response_all = $response;
$response_id = $response.id;

You need to use arrow notation in PHP to get object properties:
$response_id = $response->id
. is string concatenation in PHP, which means that in your code you probably saw the whole JSON object printed with the string id added to the end.

Related

NODE.js Lambda dynamodb documentClient get - returned data is not in [] JSON format. How to return a full JSON document datatype form GET

I'm new to Node.js/AWS lambda. Ive successfully created several documentClient QUERY functions that return a single or multiple item JSON Document in this format:
[
{
"name": "andy",
"color": "purple",
"snack": "oreos"
}
]
When I use documentClient GET and get back my single record its in THIS format, which is not playing well with the client code (apple / ios swift)
{
"name": "andy",
"color": "purple",
"snack": "oreos"
}
I'm hopign i can change the format returned from documentClient.get() to include the fill JSON document format including leading and trailing brackets .. []
I am a node.js & aws.lambda and documentClient novice, so apologies if this is a very basic question....
provided in above text
If I understood well, you're receiving an object instead of a array.
You can use the scan function to retrieve an array of results:
var params = {
TableName : 'Table',
FilterExpression : 'Year = :this_year',
ExpressionAttributeValues : {':this_year' : 2015}
};
var documentClient = new AWS.DynamoDB.DocumentClient();
documentClient.scan(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
});
Or you can transform the result to array:
const document = await documentClient.get({
TableName: "table-of-example",
Key: {
id: "id-of-example"
}
});
return [data]
Please read the document to understand more how the document dynamodb sdk works: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property

In Nodejs with querystring how to encode array with single item

I have an object like this:
const querystring = require('querystring');
let data = {
name: 'Bill',
hobbies: ['Painting', 'Running']
}
If I encode the object like this:
console.log(querystring.encode(data));
I get this:
name=Bill&hobbies=Painting&hobbies=Running
Then when I decode it:
console.log(querystring.decode(querystring.encode(data));
It comes back perfectly like this:
{
name: 'Bill',
hobbies: ['Painting', 'Running']
}
However if I pass an object with array data that has only one item in it like this:
let data = {
name: 'Bill',
hobbies: ['Painting']
}
When I encode / decode it:
console.log(querystring.decode(querystring.encode(data));
This comes back:
{
name: 'Bill',
hobbies: 'Painting'
}
Notice how it converts the array to a single string, rather than an array with a single item.
Is there anyway around this limitation with querystring? Or is there another module that handles this better? I've been looking around and can't find anything.

knex js query many to many

i'm having trouble with node & knex.js
I'm trying to build a mini blog, with posts & adding functionality to add multiple tags to post
I have a POST model with following properties:
id SERIAL PRIMARY KEY NOT NULL,
name TEXT,
Second I have Tags model that is used for storing tags:
id SERIAL PRIMARY KEY NOT NULL,
name TEXT
And I have many to many table: Post Tags that references post & tags:
id SERIAL PRIMARY KEY NOT NULL,
post_id INTEGER NOT NULL REFERENCES posts ON DELETE CASCADE,
tag_id INTEGER NOT NULL REFERENCES tags ON DELETE CASCADE
I have managed to insert tags, and create post with tags,
But when I want to fetch Post data with Tags attached to that post I'm having a trouble
Here is a problem:
const data = await knex.select('posts.name as postName', 'tags.name as tagName'
.from('posts')
.leftJoin('post_tags', 'posts.id', 'post_tags.post_id')
.leftJoin('tags', 'tags.id', 'post_tags.tag_id')
.where('posts.id', id)
Following query returns this result:
[
{
postName: 'Post 1',
tagName: 'Youtube',
},
{
postName: 'Post 1',
tagName: 'Funny',
}
]
But I want the result to be formated & returned like this:
{
postName: 'Post 1',
tagName: ['Youtube', 'Funny'],
}
Is that even possible with query or do I have to manually format data ?
One way of doing this is to use some kind of aggregate function. If you're using PostgreSQL:
const data = await knex.select('posts.name as postName', knex.raw('ARRAY_AGG (tags.name) tags'))
.from('posts')
.innerJoin('post_tags', 'posts.id', 'post_tags.post_id')
.innerJoin('tags', 'tags.id', 'post_tags.tag_id')
.where('posts.id', id)
.groupBy("postName")
.orderBy("postName")
.first();
->
{ postName: 'post1', tags: [ 'tag1', 'tag2', 'tag3' ] }
For MySQL:
const data = await knex.select('posts.name as postName', knex.raw('GROUP_CONCAT (tags.name) as tags'))
.from('posts')
.innerJoin('post_tags', 'posts.id', 'post_tags.post_id')
.innerJoin('tags', 'tags.id', 'post_tags.tag_id')
.where('posts.id', id)
.groupBy("postName")
.orderBy("postName")
.first()
.then(res => Object.assign(res, { tags: res.tags.split(',')}))
There are no arrays in MySQL, and GROUP_CONCAT will just concat all tags into a string, so we need to split them manually.
->
RowDataPacket { postName: 'post1', tags: [ 'tag1', 'tag2', 'tag3' ] }
The result is correct as that is how SQL works - it returns rows of data. SQL has no concept of returning anything other than a table (think CSV data or Excel spreadsheet).
There are some interesting things you can do with SQL that can convert the tags to strings that you concatenate together but that is not really what you want. Either way you will need to add a post-processing step.
With your current query you can simply do something like this:
function formatter (result) {
let set = {};
result.forEach(row => {
if (set[row.postName] === undefined) {
set[row.postName] = row;
set[row.postName].tagName = [set[row.postName].tagName];
}
else {
set[row.postName].tagName.push(row.tagName);
}
});
return Object.values(set);
}
// ...
query.then(formatter);
This shouldn't be slow as you're only looping through the results once.

Stringifying JSON data loses object I'm trying to stringify

I'm new to NodeJS and I'm trying to learn it a bit better by writing a Discord bot. But I'm having an issue with stringifying an object to JSON. I think it's having an issue with the array I'm setting, but I'm not sure how else I would do this. If I'm not supposed to set an array and using my guildMembers example below, how else should I insert this data into my JSON file?
I've looked through a few examples here on StackOverflow and found this particular article: JSON Stringify Removing Data From Object. However, it's not clear to me given what I'm trying to achieve.
var o = {};
var guildKey = guild.id;
o[guildKey] = [];
o[guildKey]['guildMembers'] = {};
var guildMembers = []
guild.members.forEach(function(guildMember, guildMemberId) {
if (!guildMember.user.bot){
var memberData = {
id: guildMember.id,
data: {
userName: guildMember.user.username,
nickName: guildMember.nickname,
displayName: guildMember.displayName,
joinedAt: guildMember.joinedAt
}
}
guildMembers.push(memberData);
};
});
o[guildKey]['guildMembers'] = guildMembers;
json = JSON.stringify(o);
I am expecting the data to show the guildMembers object with the array under the guildKey object. However, the JSON shows only the guildKey object with an empty array:
{"guildKey":[]}
You make guildKey an array and then try to use it as an object ...
Solution is:
o[guildKey] = {};
Just like in the mentioned post.
It is because you are assigning a key-value pair to an array with
o[guildKey]['guildMembers'] = { }; <= o[guildKey]
When iterating over an array to display the contents, JavaScript does not access non-integer keys. You should store o[guildKey] as an object instead.

How can I mask json using json-masker for fields with "-" in it?

My requirement is to mask certain fields of a JSON while logging them.I am working on node.js. I have used json-masker library of node.js. While passing the JSON path of attributes with "-" in the name in the "whitelist" parameter, I am getting lexical error.
JSON
{
"attribute1":"value1",
"attribute2":"value2",
"attribute-name":"value3"
}
Code
const masker = require('json-masker');
const mask= masker({
whitelist: ['$.attribute1','$.attribute-name']
});
Error
Error Lexical error on line 1. Unrecognized text.
$.attribute-name
Also, is there a way to specify only the attributes that needs to be masked rather that specifying the ones that need not be masked(as specified in whitelist).
Please suggest if there is a better approach to do this using any other function/library.
Please note that I am receiving this JSON , so I cannot change the key name
The correct syntax is '$["attribute-name"]' instead of '$.attribute-name'
The $ fields are processed by jsonpath, a dependency of json-masker. This issue is discussed in one of their github issues (#90) and the solution presented there.
Use maskdata npm module: https://www.npmjs.com/package/maskdata
You can mask json fields containing '-' without any extra effort. Also, you can mask the nested fields too.
Example:
const MaskData = require('./maskdata');
const maskJSONOptions = {
// Character to mask the data. Default value is '*'
maskWith : "*",
// It should be an array
// Field names to mask. Can give multiple fields.
fields : ['level1.level2.level3.field3', 'level1.level2.field2', 'level1.field1', 'value1']
};
const nestedObject = {
level1: {
field1: "field1",
level2: {
field2: "field2",
level3: {
field3: "field3",
}
}
},
value1: "value"
};
const maskedObj = MaskData.maskJSONFields(nestedObject, defaultJSONMaskOptions2);
//Output : {"level1":{"field1":"******","level2":{"field2":"******","level3":{"field3":"******"}}},"value1":"*****"}

Resources