I intend to map the output from external api to object attribute in model.
For examples, data->x to Device->$attribute_x;, data->y to Device->$attribute_y; The output is array of objects.
My expected outcome is extract each of object by access the Device model and its attributes and do some manipulation in model. (fetch once time only from API and format it in different function)
Can someone give some guideline on ways to defining methods/class to achieve?
This is my output from external API:
{
"data": [
{
"x": "1",
"y": "2"
},
{
"x": "11",
"y": "22"
}
]
}
This is model without extend Eloquent in Laravel to extract all data from external API using guzzle .
namespace App;
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://xxxx.com',
'headers' => [
'content_type' => 'application/json',
'accept' => 'application/json'
]]);
$response = $client->get('units');
$data = json_decode($response->getBody());
class Devices
{
protected $attribute_x;
protected $attribute_y;
public static function all(){
}
}
I write code from head, but you can create in Devices following method:
public static function importFromAPI($data) {
$result = [];
foreach($data as $item) {
$dev = new Device;
$dev->attribute_x = $item['x'];
$dev->attribute_y = $item['y'];
$result[] = $dev;
}
return $result;
}
And use it to import Device list from data array from API json
$devices = Devices::importFromAPI($data);
Your Device can extend eloquent Model class as well to have easy access to DB. Above method can be also implemented in separate class e.g ApiService and be renamed to importDevicesFromAPI and contains code to load json and map it to Device objects.
Related
Good Day!
I am planning to create a custom API for Account module were I am going to get and update data using API. I created a custom field (integration_ref_id) on my Account module this will serve as my identifier if the accounts is existing or not. Check bellow as payload request sample
{
"consent_timestamp": "2021-04-13 09:45:00",
"integration_ref_id": "CUSREF-202104-ABCDEF0000003",
"last_name": "De la Cruz",
"first_name": "Juan",
"birthdate": "1995-03-25",
"mobile_number": "+639171234199",
"email": "juan.delacruz#example.com",
"location_code": "LOC0001",
"street_name": "Rose St.",
"landmarks": "Mcdo",
"gender": "male"
}
Now I created custom routes on my custom folder (custom/application/Ext/Api/V8/Config)
<?php
$app->get('/my-route/{myParam}', 'MyCustomController:myCustomAction');
$app->get('/hello', function() {
return 'Hello World!';
});
$app->get('/getCustomers', 'Api\V8\Controllers\CustomersController:getCustomers');
And I place the controller same path of the routes. (custom/application/Ext/Api/V8/Controller)
And this is my controller code
<?php
namespace Api\V8\Controller;
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}
class CustomersController extends BaseController
{
public function getCustomers(Request $request, Response $response, array $args, GetRelationshipParams $params)
{
try {
$jsonResponse = $this->relationshipService->getCustomers($request);
return $this->generateResponse($response, $jsonResponse, 200);
} catch (\Exception $exception) {
return $this->generateErrorResponse($response, $exception, 400);
}
}
}
But I got this Error in postman
I keep searching, but its kinda confusing on my end. BTW I am new on this SuiteCRM
Regards!
Never mind, I was able to figure it out. I just added this code below to my controller CustomeController.php
namespace Api\V8\Controller;
use Slim\Http\Response;
use Slim\Http\Request;
And added this one to my custom controller.php
require 'custom/application/Ext/Api/V8/Controller/CustomersController.php';
use Api\V8\Controller;
use Slim\Container;
Then everything should be working.
Kindly check json response from one to many relation. I want to show this response in ajax. But i don't know how to show in ajax. how to show in success response.
{
"extra":{
"values":[
[
{
"id":9,
"extra_name":"Ihr Dip:",
"status":"open",
"created_at":"2022-04-19T16:47:35.000000Z",
"updated_at":"2022-04-19T16:47:35.000000Z",
"created_by":"1",
"updated_by":null,
"extra":[
{
"id":17,
"description":"mit Kr\u00e4uter-Remoulade",
"status":"open",
"main_extra_id":"9",
"price":"1,00",
"created_at":"2022-04-19T16:47:55.000000Z",
"updated_at":"2022-04-19T16:47:55.000000Z",
"created_by":"1",
"updated_by":null
},
{
"id":18,
"description":"mit Pizza Max Ketchup 40ml",
"status":"open",
"main_extra_id":"9",
"price":"10,70",
"created_at":"2022-04-19T16:48:14.000000Z",
"updated_at":"2022-04-19T16:48:14.000000Z",
"created_by":"1",
"updated_by":null
}
]
}
]
]
}
}
Laravel will automatically serialize your Eloquent models and collections to JSON when they are returned from routes or controllers:
Route::get('users', function () {
return User::all();
});
See below link:
https://laravel.com/docs/9.x/eloquent-serialization#relationships
Another example:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index(){
return Post::latest()
->with('category', 'author')->get();
}
}
I'm new in react-admin and I'm trying to create a new admin panel for my old API.
So when my data provider do API calls it causes me this error:
The response to 'getList' must be like { data : [...] }, but the received data is not an array. The dataProvider is probably wrong for 'getList'
The responses of my old API has various data fields like { 'posts': [] } or { 'users': [] }. How can I use these name of fields instead of { 'data': [] } ?
The 'data' in this case just refers to the type of information that should be retuned, not the name of the object.
Within your API, you can simply return a list in the following form:
const posts = [
{
"id":1,
"name":"post1"
},
{
"id":2,
"name":"post2"
},
];
return JSON.stringify(posts);
Then return that 'posts' object in your response and don't forget to set the expected ContentRange headers.
Not sure what language you are using, but the principle above should be easy enough to follow and apply in any language.
I'm currently working on a RESTful API backend using nodejs with typescript where I need to gather information from multiple different APIs and parse the result and pass on the parsed information to the frontend.
Right now I'm working on a API route where I gather information from two different external API routes, I gather the data from there with https. I send the data onward to my Objecthandler in the form [object Object],[object Object] because I push the response from my first http call into an array and my second http response into another array which I then push onto a third array that is the combined data from both responses.
const first: object [] = [
];
const second: object [] = [
];
const combined: object [] = [
];
My object handler code looks like this:
function ObjectHandlerAvainsanat(obj: any): object[] {
const keywords: object [] = [
];
if (obj instanceof Array) {
obj.forEach((e: any) => {
const results = e.results.map((x: any) => x);
const vals = {
localname: results.localname,
prefLabel: results.prefLabel,
altLabel: results.altLabel,
};
keywords.push(vals);
});
return keywords;
}
}
However, I get the error that
const results = e.results.map((x) => x);
^
TypeError: Cannot read property 'map' of undefined
The actual data inside the http response looks like this, where I want the values from inside the results object array:
{
"#context": {
"skos": "http://www.w3.org/2004/02/skos/core#",
"isothes": "http://purl.org/iso25964/skos-thes#",
"onki": "http://schema.onki.fi/onki#",
"uri": "#id",
"type": "#type",
"results": {
"#id": "onki:results",
"#container": "#list"
},
"prefLabel": "skos:prefLabel",
"altLabel": "skos:altLabel",
"hiddenLabel": "skos:hiddenLabel",
"#language": "FI"
},
"uri": "",
"results": [
{
"uri": "http://www.yso.fi/onto/yso/p22020",
"type": [
"skos:Concept",
"http://www.yso.fi/onto/yso-meta/Concept"
],
"localname": "p22020",
"prefLabel": "pyydystä ja päästä -kalastus",
"lang": "fi",
"altLabel": "catch and release -kalastus",
"vocab": "yso"
},
{
"uri": "http://www.yso.fi/onto/yso/p22337",
"type": [
"skos:Concept",
"http://www.yso.fi/onto/yso-meta/Concept"
],
"localname": "p22337",
"prefLabel": "CATCH-22",
"lang": "fi",
"vocab": "yso"
}
Does anyone here know what I'm doing wrong? Thanks in advance for all the help,
Br,
Victor
TypeError: Cannot read property 'map' of undefined
e.results is undefined. This is a fact irrespective of your result object you are showing.
Fix
console.log(e) and go from there.
(assuming e is your http response)
Based on the HTTP response you provided, e is a JSON object, so you can call:
let newVar = JSON.parse(e);
and then try to pull results using:
newVar.results.map((x: any) => x);
Hope this helps...
I have an API that accepts data format as [ { "record_id": "TestID3" } ]. I am trying to send record_id field using the form below in my angular project:
html:
<input id="record_id" type="text" class="form-control" [(ngModel)]="member.record_id" name="record_id" #record_id="ngModel" placeholder="Enter Record ID">
component.ts:
export class MembersAddComponent implements OnInit {
member: Array<Object> = [];
constructor(private service: DataService ) { }
ngOnInit() {
}
submit() {
this.service.importRecord(this.member).subscribe(member => {
this.member = member;
}, error => {
console.log(error);
});
}
}
And my service.ts:
importRecord(data): Observable<any> {
const formData = new FormData();
formData.append('token', this.token);
formData.append('content', this.content);
formData.append('format', this.format);
formData.append('returnFormat', this.returnFormat);
formData.append('type', this.type);
formData.append('overwriteBehavior', this.overwriteBehavior);
formData.append('forceAutoNumber', this.forceAutoNumber);
formData.append('data', data);
formData.append('returnContent', this.returnContent);
return this.http.post(this.baseUrl, formData).map(res => res.json())
.catch(this.handleError);
}
The error that I get is below:
{"error":"The data being imported is not formatted correctly. The JSON must be in an array, as in [{ ... }]."}
I also tried member:any = {}, member:Object = {}; but I got the same error. I am thinking that I am unable to format my member object as requested format. But I couldn't make it as desired format.
[ { "record_id": "TestID3" } ]
That is an array, containing a single element, which is an object.
member: Array<Object> = [];
that defines an array with no element at all.
[(ngModel)]="member.record_id"
That will try to read and write the property record_id of member, which is an array. It will not magically add an element to the array and set its property.
So what you need is an object that will be populated by the form. And then you need to put that object into an array before to send the array to the API.
Start by defining an interface to describe your object:
interface Member {
record_id: string;
}
Then use one as the model for your form:
member: Member = {
record_id: '';
};
...
[(ngModel)]="member.record_id"
Then put that member into an array before sending it:
submit() {
const data: Array<Member> = [this.member];
this.service.importRecord(data)...
It's difficult to tell if this is due to an incorrectly formatted response from the POST or the body of the POST.
Things you can do:
Check the network tab in Chrome to verify that the request is being sent, it's content is valid JSON (use an online validator)
Check your API backend to see if the data you're sending is being saved, if so the error is with the format of the JSON in your response.
Verify in Chrome that the response data in the network request is valid JSON.
If all of these are true, you may need to consider using headers such as {requestType: 'json'} as detailed in the Angular docs here: Request/Response Headers
If these are not true, then you will need to change the model of the object you are sending to reflect the object which is expected.