retrieve an array in php after passing from angular js - javascript

I have an array like this
$scope.kk = [
{ name:'Computer Architecture', price:65 },
{ name:'Advanced Composite Materials', price:45 },
{ name:'Stategies Unplugged', price:43 },
{ name:'Teaching Science', price:50 },
{ name:'Challenging Times', price:22 }];
I have passed this array to my controller through webapi like this
var req1= {
method: 'POST',
url: apiPoint.url + 'sin.php',
headers: {
'Content-Type': 'application/json'
},
params :{
"fulldet[]" : $scope.kk
}
$http(req1).then(function (response) {
if (response.data.status) {
alert(JSON.stringify(response.data));
}
}
And in my controller i need to extract this array
I have used foreach statement like this
$result['ppp'] = $fulldet;
foreach($fulldet as $e){
$result['lm']=$e['name'];
}
But am getting ILLEGAL STRING OFFSET 'name'
Please help me.
For my reference i hv printed my array back after the response from controller. I get it like this
{"ppp":["
{\" name\":\"Computer Architecture\", \"price\":65 },
{\" name\":\"Advanced Composite Materials\", \"price\":45 },
{ \"name\":\"Stategies Unplugged\", \"price\":43 },
{\" name\":\"Teaching Science\", \"price\":50 },
{\" name\":\"Challenging Times\", \"price\":22 }"]}

Before trying to iterate over array apply json_decode to it.
$result['ppp'] = json_decode($fulldet, true);
foreach($fulldet as $e){
$result['lm']=$e['name'];
}

as i see now, your problem is when you try to get the data on the server side (sorry , for previous answer).
the parameter that you pass inside the request should be string not array
so you change this:
params :{
"fulldet[]" : $scope.kk
}
to this:
params :{
"fulldet" : $scope.kk
}
try to get your POST data like this:
$results = json_decode(file_get_contents('php://input),true);
foreach($results as $item){
echo $item['name'];
}

Related

Posting JSON and parsing it with php://input is not working

I want to create an object by sending a json to my webserver and parsing the information.
My javascript looks like this:
import { HTTP } from '#ionic-native/http/ngx';
....
constructor(private http: HTTP){}
...
// combining and sending the information below
createMediaObject(): Observable<any> {
var url = `${ApiServerUrl}/add_mo`;
url = encodeURI(url);
var convertedData = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [Number(this.mediaObjectForm.value.lng).toString(), Number(this.mediaObjectForm.value.lat).toString()]
},
properties: {
icon: this.mediaObjectForm.value.icon.toString(),
tags: this.mediaObjectForm.value.tags.toString(),
topic: this.mediaObjectForm.value.topic.toString(),
title: this.mediaObjectForm.value.name.toString(),
description: this.mediaObjectForm.value.description.toString(),
rotation: this.rotation.toString(),
media: this.mediaObjectForm.value.contents.toString()
}
};
return from(this.http.post(url, convertedData, {})).pipe(map(res => res.data));
}
Now I want to parse the informatik in php using the solution from this post get POSTed JSON Array in php:
$params = json_decode(file_get_contents("php://input"), true);
echo json_encode(array("status" => empty($params)));
try {
// get posted data
echo $params["type"];
if (isset($params["properties"]["topic"])) {
$object->topic = $params["properties"]["topic"];
echo $object->topic;
}
However:
echo json_encode(array("status" => empty($params)));
Output: {"status" : "true"} -> that means that something went wrong and params is empty
same with
echo $object->topic;
Output: null
Is there a problem in the frontend or backend?
Do I need to change something inside of my configs?

Fail to load response data jquery.easy-autocomplete.min.js:10 WARNING:

I am using the easyautocomplete, http://easyautocomplete.com/, to populate a list as the user types in a search field. The code is as follows:
var options = {
url: function(phrase) {
if (phrase !== "") {
return "http://<url>/todo?query=" + phrase + "&format=json";
} else {
return "http://<url>/todo?query=empty&format=json";
}
},
getValue: "results",
ajaxSettings: {
dataType: "jsonp"
},
requestDelay: 300,
theme: "round"
};
$("#product-list").easyAutocomplete(options);
I am getting a response from my API that looks like:
{
"results": [
"list_item_1",
"list_item_2",
"list_item_3",
...
"list_item_50"
]
}
I have a feeling I'm not formatting the response properly, but I'm not sure how to fix it.
A look through the guide it looks like getValue would be if you had an array of objects and wanted to pull a particular key from each one. From the list location section it looks like you are looking for listLocation to specify the object key that has the array of things to autocomplete. So changing getValue to listLocation should give you the results you are looking for

Duplicate keys in a REST connector query in loopback

I would like to ask if you know how could I duplicate parameters in a loopback REST connector query.
I have the following code:
details: {
'template': {
'method': 'GET',
'debug': true,
'url': 'https://www.example.com/data',
'timeout': 10000,
'headers': {
'Authorization': 'Bearer {token}'
},
'query': {
q: 'PHOTOS'
q: 'DETAILS',
id: '{id}'
},
'options': {
'useQuerystring': true
},
'responsePath': '$'
},
'functions': {
'searchData': [
'token',
'id'
]
}
}
The problem for that it is that it seems that loopback override the value of the parameter q by the last one, because I get only information for the last parameter.
Any idea how to solve it?
Thank you in avance.
You just have to pass them as an array:
'query': {
q: ['PHOTOS', 'DETAILS'],
id: '{id}'
},
Note that the options key, is passed to request and here's the documentation for useQuerystring:
useQuerystring - If true, use querystring to stringify and parse querystrings, otherwise use qs (default: false). Set this option
to true if you need arrays to be serialized as foo=bar&foo=baz
instead of the default foo[0]=bar&foo[1]=baz.
So if you remove it you'll end with something like ?q[0]=PHOTOS&q[1]=DETAILS.
You can also another option there:
qsStringifyOptions - object containing options to pass to the qs.stringify method.
Alternatively pass options to the
querystring.stringify
method using this format {sep:';', eq:':', options:{}}. For example,
to change the way arrays are converted to query strings using the qs
module pass the arrayFormat option with one of
indices|brackets|repeat
So you can actually end up with the same thing adding this:
"options": {
"qsStringifyOptions": {
"arrayFormat": "repeat"
}
}
And if you want to have just the brackets(something like this ?q[]=PHOTOS&q[]=DETAILS) you can specify brackets option:
"options": {
"qsStringifyOptions": {
"arrayFormat": "brackets"
}
}

Select2 - Pass back additional data via ajax call

Ok, I feel like I'm going crazy here. I'm using the select2 jquery plugin (version 4), and retrieving data via ajax. So you can type in a name, and it will return that contact information. But I also want to return what organization that contact is a part of.
Here is my select2 initialization:
$('#contact_id').select2({
ajax: {
url: 'example.com/contacts/select',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term,
page: params.page
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
minimumInputLength: 3,
maximumSelectionLength: 1
});
And here is the data I'm returning (laravel framework):
foreach($contacts as $con) {
$results[] = [
'id' => $con->contact_id,
'text' => $con->full_name,
'org' => [
'org_id' => $con->organization_id,
'org_name' => $con->org_name
]
];
}
return response()->json($results);
So isn't 'org' supposed to be attached to either the created option or select element by select2? So I could do something like $('#contact_id').select2().find(':selected').data('data').org or $('#contact_id').select2().data('data').org or something like that?
Idealistically, this would look like:
<select>
<option value="43" data-org="{org_id:377, org_name:'Galactic Empire'}">Darth Vader</option>
</select>
I swear I confirmed this worked last week, but now it's completely ignoring that org property. I have confirmed that the json data being returned does include org with the proper org_id and org_name. I haven't been able to dig anything up online, only this snippet of documentation:
The id and text properties are required on each object, and these are the properties that Select2 uses for the internal data objects. Any additional paramters passed in with data objects will be included on the data objects that Select2 exposes.
So can anyone help me with this? I've already wasted a couple hours on this.
EDIT: Since I haven't gotten any responses, my current plan is to use the processResults callback to spawn hidden input fields or JSON blocks that I will reference later in my code. I feel like this is a hacky solution given the situation, but if there's no other way, that's what I'll do. I'd rather that than do another ajax call to get the organization. When I get around to implementing it, I'll post my solution.
Can't comment for now (low reputation).. so... answering to slick:
Including additional data (v4.0):
processResults: function (data) {
data = data.map(function (item) {
return {
id: item.id_field,
text: item.text_field,
otherfield: item.otherfield
};
});
return { results: data };
}
Reading the data:
var data=$('#contact_id').select2('data')[0];
console.log(data.otherfield);
Can't remember what I was doing wrong, but with processResults(data), data contains the full response. In my implementation below, I access this info when an item is selected:
$('#select2-box').select2({
placeholder: 'Search Existing Contacts',
ajax: {
url: '/contacts/typeahead',
dataType: 'json',
delay: 250,
data: function(params){
return {
q: params.term,
type: '',
suggestions: 1
};
},
processResults: function(data, params){
//Send the data back
return {
results: data
};
}
},
minimumInputLength: 2
}).on('select2:select', function(event) {
// This is how I got ahold of the data
var contact = event.params.data;
// contact.suggestions ...
// contact.organization_id ...
});
// Data I was returning
[
{
"id":36167, // ID USED IN SELECT2
"avatar":null,
"organization_id":28037,
"text":"John Cena - WWE", // TEXT SHOWN IN SELECT2
"suggestions":[
{
"id":28037,
"text":"WWE",
"avatar":null
},
{
"id":21509,
"text":"Kurt Angle",
"avatar":null
},
{
"id":126,
"text":"Mark Calaway",
"avatar":null
},
{
"id":129,
"text":"Ricky Steamboat",
"avatar":null
},
{
"id":131,
"text":"Brock Lesnar",
"avatar":null
}
]
}
]

How to alter the data returned by $resource in Angular.js?

I'm using an API that returns JSON data in this format:
{
paging: {
previous: null,
next: null
},
data: [
{ title: 'First Item' },
{ title: 'Second Item' },
...
]
}
I'm using Angular's $resource service to fetch this data.
My code - which is located in a controller - goes something like this:
var Entity = $resource('/api/entities');
var entities = $scope.entities = Entity.get();
And then, in the view, I can display the data like this:
<ul>
<li ng-repeat="entity in entities.data">{{entity.title}}</<li>
</ul>
It all works fine, but:
I'd rather expose only the contents of entities.data to the view, instead of the whole entities object. How can I intercept the data returned by the GET request to modify it before it populates $scope.entities?
Correlated question: since I am fetching an array of data, it would be cleaner to use Entity.query() instead of Entity.get(). But if I use Entity.query() in the code above, I get an error "TypeError: Object # has no method 'push'". This makes sense, since the API is returning an object instead of an array (hence, no 'push' method on the object). Again, if I could extract the .data attribute from the response, I'd have an array.
Following these indications by Dan Boyon, I managed to customize the default $resource service and to override the .get() or .query() methods, but I'm not sure where to go from there.
I don't think you need to modify the get or query defaults. Just use the success callback to do what you want. It should be more robust as well.
Entity.get(
{}, //params
function (data) { //success
$scope.entities = data.data;
},
function (data) { //failure
//error handling goes here
});
Html will be cleaner, too:
<ul>
<li ng-repeat="entity in entities">{{entity.title}}</<li>
</ul>
By the way, I usually declare services for my resources and then inject them into my controllers as I need them.
myServices.factory('Entity', ['$resource', function ($resource) {
return $resource('/api/entities', {}, {
});
}]);
You can use the Response Transformer (transformResponse) like this:
$resource('/api/entities', {}, {
query: {
method: 'GET',
responseType: 'json',
isArray: true,
transformResponse: function (response) {
return response.data;
}
}
});
This code modifies the "query" method behaviour, you can do the same for "get" ... !

Categories

Resources