Get all Data in a Body using Guzzle in Laravel from External API - laravel

I want to retrieve only the email in a JSON response using guzzle in Laravel from an external API. Here is what I have tried
//Get all customer
$allcus = 'https://api.paystack.co/customer';
$client = new Client();
$response = $client->request('GET', $allcus, [
'headers' => [
'Authorization' => 'Bearer '.'sk_live_#########################',
],
]);
$cus_data = json_decode($response->getBody()->getContents());
//returns a json response of all customers
//dd($cus_data);
$cus_data_email = $cus_data->data->email;
dd($cus_data_email);
Using this returns error
$cus_data_email = $cus_data->data->email;
"message": "Trying to get property 'email' of non-object"
But when I tried this, it returns the customer in the first array
$cus_data_email = $cus_data->data[0]->email;
I don't want to return just one customer email. I want to retrieve all of the customers' emails.
This is the way the JSON response is
{
"status": true,
"message": "Customers retrieved",
"data": [
{
"integration": ######,
"first_name": null,
"last_name": null,
"email": "a###$gmail.com",
"phone": null,
"metadata": null,
"domain": "live",
"customer_code": "CUS_##########",
"risk_action": "default",
"id": #######,
"createdAt": "2020-05-26T00:50:12.000Z",
"updatedAt": "2020-05-26T00:50:12.000Z"
},
...

What you're looking for is a loop!
$cus_data->data is an array, which is a variable that can store multiple values at once. These can be accessed with an index, and are commonly seen with loops.
I highly suggest reading the two links I supplied, the loop I'll be using is a foreach loop, as it's the most readable in this context. All the loops have their place, so it would pay to get familiar with them.
$emailsArray = []; // initialise an array
$emailsString = ""; // initialise a string
// Here's our loop, which will go over all the values of $cus_data->data
foreach($cus_data->data as $datum) {
// $datum is the single value in $cus_data->data which we're currently looking at
// Each of these values have an email property, which we access with arrow notation
array_push($emailsArray, $datum->email); // add the email to our array
$emailsString = $emailsString . $datum->email . ", "; // add the email to our string
}
Following this, $emailsArray will be an array (like we learned about above!) with all the emails from $cus_data->data.
$emailsString will contain the same information, just in a comma-separated string.
One thing to watch out for is if some of your data doesn't have emails! Then the code above could fail.
Admittedly, this isn't the shortest solution. For a problem like this, I would probably use array_map. The code here does the same thing in a more verbose format so we can understand it better.

Related

Laravel Fractal add success message to response

Is it possible to add a success message to a JSON response using Fractal? I would like the structure to look like the following
{
"success": true,
"message": "Clients found",
"_metadata": {
"total_count": 2
},
"data": {
"clients": [
]
}
}
I have written the following code to return the data
$response_data = fractal()
->collection($person_array)
->transformWith(new ResponseTransformer())
->toArray();
Do I need to create a new serialiser to get this format? I have been following this documentation https://packagist.org/packages/spatie/fractalistic but there is no option to add extra key values such as success: true.
I also want to use this format for all my API responses, is it possible to create a generic Transformer which returns what ever array data I pass into it instead of creating a Transformer per Model?
Laravel fractal allows to add meta data to collections :
fractal()
->addMeta([
'status' => [
'success' => true,
'code' => 1,
'message' => 'Test'
]
])
Resulting JSON output
"meta": {
"status": {
"success": true,
"code": 1,
"message": "Test"
}
}

How to use the "nextToken" parameter to test Pagination?

I am working with a sample of graphql query which I want to further bind to a FlatList object in a React-Native app. But I am still struggling to understand what I should pass on then nextToken parameter in order to get a slice of objects destined to a second page...
Tried to pass the next or last id or index, but it didn't work - it asks me to provide a valid nextToken, which I don't know what kind of data it is.
I'm running through AppSynch console.
My query:
query ListResources(
$nextTokenPlants: String = "Orange Tree"
$limitPlants: Int = 3
) {
listResources {
items {
id
name
Plants(limit: $limitPlants, nextToken:$nextTokenPlants) {
items {
id
name
filterName
description
bath
tea
insence
children
}
nextToken
}
}
nextToken
}
}
This is the result I get:
{
"data": {
"listResources": {
"items": [
{
"id": "361dee16-d567-41ed-b1d4-9baa4a7ffdcc",
"name": "Plantas",
"Plants": null
}
],
"nextToken": null
}
},
"errors": [
{
"path": [
"listResources",
"items",
0,
"Plants"
],
"data": null,
"errorType": "DynamoDB:UserIllegalArgumentException",
"errorInfo": null,
"locations": [
{
"line": 9,
"column": 7,
"sourceName": null
}
],
"message": "com.amazonaws.deepdish.common.pagination.InvalidPaginationTokenException: Invalid pagination token given."
}
]
}
I expected to get a list of 3 of the itens stored on "Plants", starting from the "Orange Tree" onwards... Could anyone pls shed some light on it?
nextToken is a String that you get in the response when you send a request, looks like
eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGdtYVZObHlaR3FSa3hDRnFVWWdFeEZDM0FMY1JRdE9UOEt2dWFLMExzcjJ3RlBPMGdpcC96bjQ5VjFOVElKUng1M0FBQUNlVENDQW5VR0NTcUdTSWIzRFFFSEJxQ0NBbVl3Z2dKaUFnRUFNSUlDV3dZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF4VEt5Myt3RUJuSzVSU2hsUUNBUkNBZ2dJc1lmdDk2WVVmQ053Tms2WGkxc3Z2bUgzSGFQZTdNTm1DQWhDcWJ5RFlydXZwTmR6WUNBQ0pJS1RZQlVWdk1xbU9EV2s2SVdLTzlqNmRhenNWZGZYTmFTQmxseE9yUS9BZWY0c2NpL1duWVUweWEyNCthZGQxcVNaMGZEWDZUdkJDak1XQjQ4QmhTQmxLejk2TFpiZ3pDN3dJTzVPRStFbUxHdVhRcURXcUpNZDM3Rm0yNUdiQVU1Tlg1YWVtWE1PbnVKSkZpTzA3U3ZhdUVZMWZwaXZCVU9pMHlxTVlIYk5PMkQ4aDZRVmQ4eW4yTXl3YU9UUHYwWFJZNitrakgvNGlyOWtrdlVXK1pvNFdOeDFBL2h1MlF4Z0lSczQ3d0xTT2NsaXk1Y3o0eFFzM2xqREhYL3M0TTVwT2phTCt0TGpYOUlWcGZCVW45bUgwWEw4ZEFkR0VZRGdjeWpMUHlPdWFnREVNMWR4M09neTg4NGJPclJ3VVgrRmM0UHpGekRqSHZjcjBGSVVXNEM2ZUxzYVRtRjNFakhLRk9ERllDWWkrQ01QNFg0a0dCdTFJQ3BLQjNJdEx2VTZHcUxNVDRMd3NJbkk4SVBhZm1MRnYxRTZDbWxxMnFKZ2wxY1BEVmR6MVFDc0Ezby9vR0VHUkI2VkJtc3VFSUFuOW10OVJzaWpyaklqUm5DQzlSWHA3NnA0WlhWanBJY0dSVU9GTktvZGNnMVpNbGV0a200clhBUGJacFZ5TDdkcnQyTXlEVERQd1crcjZsRHJUUVJJZzI4MEl3Y3ZkQzB1RWRrb0hqTlZPR0kwSWxsSnZ5RjRWTCtNNzRuWXcwNVNSWllJODdGcGdzR21LZjRvWVA1VG9temRVUUR0YWkrZVRJcUxGRjlGYzk0UUNwZlYrVlpmeVU0Mk4yTnRtNi9MYUhrZ08zdGRTUHN1bGhQWVRuMGRQNU5aWG5pODU1eGZyL1N2dDQ2VU0xb3I2UEE9PSJ9
and it has nothing to do with your table keys.
Let me explain now how does it work:
When you send the request for the first time, you don't send nextToken since you don't have it and then you get the first portion of your data.
When you receive that first portion, if there exist more data, you get nextToken in the response.
Now, you have nextToken, you send another request to get the 2nd portion of your data. You should send that token in the request, so your backend knows from where to start.
You get your 2nd portion of data and a new nextToken if there is still some data to fetch (then you need to repeat step 2) or null in nextToken if there is no more data.
I hope that it's clear now

Laravel Api resource controller json format

I managed to change the format for the json response of the laravel resource controller for APIs, i want to make a key -> value response but i cant find the way to remove the brackets:
the response i get is this:
{
"1": [
{
"updated_at": 1536147154
}
],
"2": [
{
"updated_at": 1536160598
}
]
}
but i want it to be like this:
{
"1":
{
"updated_at": 1536147154
},
"2":
{
"updated_at": 1536160598
}
}
I get the response from an eloquent collection, and then I group it by id, but I don't know how to get rid of the brackets because the values end in an array.
I don't know if I am clear in my question.
Solved it, i removed the groupby and instead, I used the keyBy to assign their id as a key.
Transformers can be used to format json
I used https://github.com/spatie/laravel-fractal to format my json response in controllers

Google Drive API upload file with custom property, properties missing from response

I am trying to save a google drive file with custom properties, but its not working and due to the very poor documentation of the Google API, i am struggeling with this. Here is my code so far:
$g = new FileCtrl();
$fileMeta = new Google_Service_Drive_DriveFile();
$fileMeta->name = $file['name'];
$fileMeta->parents = [$g->googleDriveFolderId];
$fileMeta->appProperties = (object)['lead_id'=>$file['lid'], 'sales_package_id'=>$file['pid'], 'user_id'=>$user->uid];
//$fileMeta->size = $file['size'];
$fileData = array(
'data' => $fileContent,
'mimeType' => $file['media_type'],
'uploadType' => $file['multipart'],
);
//create file in google drive
$res = $g->client->files->create($fileMeta, $fileData);
It is not returning an error and the event is saved, but without the custom properties!?
You are probably looking for the properties in the returned file resource.
The reason they aren't there is that Drive only returns a small number of the file properties (name, mime type, id). If you want to see the full file resource you need to include fields=* in the request. So a correct request would look something like
POST https://content.googleapis.com/drive/v3/files?fields=*
I don't know the PHP library, so you'll need to figure that bit out. It will be something like
'fields' => '*',
I just tested this.
Request:
{
"name": "Linda Test",
"mimeType": "application/vnd.google-apps.document",
"appProperties": {
"TestingId": "1"
}
}
Response:
{
"kind": "drive#file",
"id": "1mhP2EW4Kbl81F5AuJ4zJ2IPoeI56i_Vd5K-dfGJRj6Y",
"name": "Linda Test",
"mimeType": "application/vnd.google-apps.document"
}
Do a file.get to check the file metadata.
{
"kind": "drive#file",
"id": "1mhP2EW4Kbl81F5AuJ4zJ2IPoeI56i_Vd5K-dfGJRj6Y",
"name": "Linda Test",
"mimeType": "application/vnd.google-apps.document",
"starred": false,
"trashed": false,
"explicitlyTrashed": false,
"parents": [
"0AJpJkOVaKccEUk9PVA"
],
"appProperties": {
"TestingId": "1"
},
...
}
I suggest you check your uploaded file using the File.get method after its returned to be sure that it was added. To my knowledge there is now way to see these added fields via the Google drive website interface. If after ruining a file.get you still find that it wasn't uploaded i suggest you log this as a bug with the Google APIs PHP client library team. This works with raw rest requests it could be an issue with the library.

How to read value from JSON object?

I'm trying to read individual value from be json array object to display in the page. I have tried with below code but couldn't make it. Please advise what am i doing wrong here.
Apperciate your help.
You can get the length of a JavaScript array via its property length. To access the array Reference in your object, you can use dot notation.
In combination, the following should do what you expect:
var obj = {
"Reference": [
{
"name": "xxxxxxxx",
"typeReference": {
"articulation": 0,
"locked": false,
"createdBy": {
"userName": "System",
},
"lastModifiedBy": {
"userName": "System",
},
"lastModified": 1391084398660,
"createdOn": 1391084398647,
"isSystem": true
},
...
},
...
]
};
console.log(obj.Reference.length);
In case you are actually dealing with a JSON string, not a JavaScript object, you will need to parse it first via JSON.parse().
You get the length of an array by simply access the length attribute.
For example [0,1,2,3].length === 4.
If you just want to loop through the array, use forEach or map instead of a for loop. It's safer, cleaner, less hassle and you don't meed to know the length.
E.g.
[0,1,2,3].forEach(num => console.log(num))

Resources