I have a search bar where upon searching i get all the related products, i want to display just top 5 of them
public function getProducts()
{
if (request()->ajax()) {
$search_term = request()->input('term', '');
$location_id = 1;
$check_qty = request()->input('check_qty', false);
$price_group_id = request()->input('price_group', null);
$business_id = request()->session()->get('user.business_id');
$not_for_selling = request()->get('not_for_selling', null);
$price_group_id = request()->input('price_group', '');
$product_types = request()->get('product_types', []);
$search_fields = request()->get('search_fields', ['name', 'sku']);
if (in_array('sku', $search_fields)) {
$search_fields[] = 'sub_sku';
}
$result = $this->productUtil->filterProduct($business_id, $search_term, $location_id, $not_for_selling, $price_group_id, $product_types, $search_fields, $check_qty);
return json_encode($result);
}
}
You can use ->limit(5)->get() to get only 5 product from query
Use orderBy('column_name', 'desc' or 'asc') for sorting the results of the query
You can use laravel standard response json to send back response instead of wrapping inside json_encode
return response()->json($result)
Related
I am trying for a day now and cannot solve this problem:
I have a website where I can add contacts to a SQLite database. I want to query the database by studentID or nachname (this means last name). I have an API endpoint which seems to be working and a getContact function which only works for the first parameter. In this case it only searches for studentID and if I change the order I can only get my data by nachname.
For now I just want to display the response simply at the URL localhost:8000/api/contacts/studentID or /nachname to see the json response.
I tried this getContact function:
async getContact(**studentID, nachname**) { //here only the first parameter works
let result = [];
let query;
let params = [];
if (studentID && !nachname) {
query = "SELECT * FROM contacts WHERE studentID = ?";
params.push(studentID);
} else if (nachname && !studentID) {
query = "SELECT * FROM contacts WHERE nachname = ?";
params.push(nachname);
} else if (studentID && nachname) {
query = "SELECT * FROM contacts WHERE studentID = ? OR nachname = ?";
params.push(studentID, nachname);
}
result = await new Promise((resolve, reject) => {
db.all(query, params, (error, row) => {
if (error) {
reject(error);
} else {
resolve(row);
}
});
});
return result;
}
My API endpoint (setup with Express.js in Node.js) looks like this currently:
app
.get("/api/contacts/:studentID?/:nachname?", async (request, response) => {
const studentID = request.params.studentID;
const nachname = request.params.nachname;
console.log(request.params.studentID);
console.log(request.params.nachname);
const contact = await contactsManager.getContact(studentID, nachname);
if (contact) {
response.status(200).send(contact);
} else {
response.status(404);
}
})
I don't understand why the getContact function only works with the first parameter.
One strange thing I recognized: Right now I could search for localhost:8000/api/contacts/1 and would see the right entry, and when I add .../contacts/1/Behrens I see the entry with the ID 1 and also the entries of the people named Behrens. Maybe this information helps?
The issue is that in your getContact function, you are using the ** operator in front of studentID and nachname, which is causing them to be treated as keyword arguments instead of regular arguments. As a result, the function is only able to identify and use the first argument passed to it, while the second argument is ignored.
To fix this, you should remove the ** operator from the function definition so that the function takes in two regular arguments:
async getContact(studentID, nachname) {
// ...
}
Also, you can use SELECT * FROM contacts WHERE studentID = ? AND nachname = ? instead of SELECT * FROM contacts WHERE studentID = ? OR nachname = ? if you want to check the both parameter are exist in the database.
Also, you should check for the existence of the parameters in the API endpoint before passing them to the getContact function, otherwise, you may end up passing undefined values to the function which will cause an error.
app.get("/api/contacts/:studentID?/:nachname?", async (request, response) => {
let studentID = request.params.studentID;
let nachname = request.params.nachname;
if(!studentID) studentID = null;
if(!nachname) nachname = null;
console.log(studentID);
console.log(nachname);
const contact = await contactsManager.getContact(studentID, nachname);
if (contact) {
response.status(200).send(contact);
} else {
response.status(404);
}
})
Also, you can use only one parameter in the endpoint and use if-else statements to check which parameter is passed and then act accordingly in the function.
app.get("/api/contacts/:param?", async (request, response) => {
let studentID = request.params.param;
let nachname = request.params.param;
if(studentID.match(/^\d+$/)){
studentID = request.params.param;
nachname = null;
}else{
studentID = null;
nachname = request.params.param;
}
console.log(studentID);
console.log(nachname);
const contact = await contactsManager.getContact(studentID, nachname);
if (contact) {
response.status(200).send(contact);
} else {
response.status(404);
}
})
This should fix the issue with the getContact function only working with the first parameter, and allow you to query the database by both studentID and nachname.
I am using laravel and vuejs to create a chat app. I have encrypted my response in laravel by doing like this as I do not want anyone to see my response in console also:-
public function get()
{
$contacts = User::where('id', '!=', auth()->id())->get();
$unreadIds = Message::select(\DB::raw('`from` as sender_id,count(`from`) as messages_count'))
->where('to', auth()->id())
->where('read', false)
->groupBy('from')
->get();
$contacts = $contacts->map(function($contact) use ($unreadIds) {
$contactUnread = $unreadIds->where('sender_id', $contact->id)->first();
$contact->unread = $contactUnread ? $contactUnread->messages_count : 0;
return $contact;
});
$contacts = base64_encode($contacts);
return response()->json($contacts);
}
Now when I wish to access this value to display data in vue js, I am doing something like this:-
axios.get(this.globalUrl+'/contacts')
.then((response) => {
let encryptData = atob(response.data);
console.log(encryptData);
//data received after de-converting
/*[{"id":2,"phone":null,"name":"Casimir Morar MD","email":"clint.haag#hartmann.info","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":3,"phone":null,"name":"Lina Prosacco","email":"okeefe.camila#gmail.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":4,"phone":null,"name":"Miss Aglae Emard DDS","email":"qcarter#yahoo.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":5,"phone":null,"name":"Demarco Kilback","email":"kessler.coy#swift.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":6,"phone":null,"name":"Tyrell Ziemann Sr.","email":"clementina.kautzer#price.org","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":7,"phone":null,"name":"Ella Hand","email":"areichel#watsica.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":8,"phone":null,"name":"Dr. Maxie O'Hara DDS","email":"wallace31#yahoo.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":9,"phone":null,"name":"Mrs. Mattie Monahan IV","email":"ernser.pasquale#hotmail.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":10,"phone":null,"name":"Bradly Crona","email":"lehner.cordie#pagac.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0},{"id":11,"phone":null,"name":"Orland Kihn","email":"jacobs.wyman#yahoo.com","profile_image":null,"created_at":null,"updated_at":null,"unread":0}]*/
let finalArray = encryptData.map(function (obj) {
return obj;
//this.contacts.push(obj);
});
console.log(finalArray);
this.contacts = finalArray;
});
Here I am getting the data in the encryptData variable as an array of objects but proceeding further, every time I am getting this error:-
Uncaught (in promise) TypeError: encryptData.map is not a function
Please help me in finding the solution thanks.
You're probably missing a JSON.parse call:
axios.get(this.globalUrl + '/contacts')
.then((response) => {
let encryptData = JSON.parse(atob(response.data));
let finalArray = encryptData.map(function(obj) {
// ...
});
this.contacts = finalArray;
});
Basically:
your PHP script returns the base64-encoded data, in JSON format,
axios.get's callback receives this as a base64-encoded string,
atob base64-decodes the string (it's still a string at this point),
JSON.parse transforms it back into the actual data.
I have an array :
[{"IDAlokasiEmiten":154,"IDOrganization":12,"NamaOrganization":null,"CodeEmiten":"ANTM","NameEmiten":"AAneka Tambang (Persero) Tbk"},{"IDAlokasiEmiten":0,"IDOrganization":null,"NamaOrganization":null,"CodeEmiten":"ADHI","NameEmiten":"Adhi Karya (Persero) Tbk"}]
How do I change some values before I post to API?
I want POST to API into:
[{"IDAlokasiEmiten":0,"IDOrganization":12,"NamaOrganization":null,"CodeEmiten":"ANTM","NameEmiten":"AAneka Tambang (Persero) Tbk"},{"IDAlokasiEmiten":0,"IDOrganization":12,"NamaOrganization":null,"CodeEmiten":"ADHI","NameEmiten":"Adhi Karya (Persero) Tbk"}]
Here is my AngularJS:
// GET Detail Alokasi Emiten
$scope.emit.detailDaftarEmiten = [];
$scope.addItemAlokasi = function () {
$scope.emit.detailDaftarEmiten.push({
IDAlokasiEmiten: 0,
IDOrganization: 12,
NamaOrganization: '',
CodeEmiten: $scope.emit.detailDaftarEmiten.CodeEmiten,
NameEmiten: $scope.emit.detailDaftarEmiten.NameEmiten
});
$scope.emit.detailDaftarEmiten.IDAlokasiEmiten = '';
$scope.emit.detailDaftarEmiten.IDOrganization = '';
$scope.emit.detailDaftarEmiten.NamaOrganization = '';
$scope.emit.detailDaftarEmiten.CodeEmiten = '';
$scope.emit.detailDaftarEmiten.NameEmiten = ''
};
$scope.resetForm = function () {
$scope.emit.detailDaftarEmiten.IDAlokasiEmiten = '';
$scope.emit.detailDaftarEmiten.IDOrganization = '';
$scope.emit.detailDaftarEmiten.NamaOrganization = '';
$scope.emit.detailDaftarEmiten.CodeEmiten = '';
$scope.emit.detailDaftarEmiten.NameEmiten = ''
};
$scope.deleteItem = function (index) {
$scope.emit.detailDaftarEmiten.splice(index, 1);
};
$scope.getTotalItems = function () {
return $scope.detailDaftarEmiten.length;
};
But it doesn't work :(
I want to set all value array for (IDAlokasiEmiten=0 and IDOrganization=12).
While you raising the post request you keep your array data (your desired data) in the body of post request.for an example:
http.post(url,{(your data(key-ordered pair)})
Which returns the promises from the promises you will access the results.
. Hope its helpfull
I'm using Angularjs with the dirPagination plugin to connect with an Web API. This seems to work fine. I added a search function, to do a server side search:
$scope.searchChanged = function () {
if ($scope.searchFor.length == 0) {
$scope.calculatedValue = 'e';
} else {
vm.getData(vm.pageno, vm.getSearch($scope.searchFor));
}
}
vm.getSearch = function (query) {
if (query == undefined) {
query = 'tech';
} else {
query = query;
}
return query;
}
See Plnkr for the full code
If I start searching (e.g. sales) the API returns results and the paging is correct, the get request is:
/api/students/?category=sales&begin=1&pageSize=10
But if you want to go to another page number, the get request to the server is:
/api/students/?category=tech&begin=2&pageSize=10
How can the view remember the query 'sales', so that the paging and results are correct?
You are making a common mistake here: You don't need to pass in variable from the view if you are already using a scope variable.
Changing to this would be much less error prone
// change this to var getSearch or function getSearch if you don't need it on the view anymore
vm.getSearch = function () {
var query = vm.searchFor;
// you should only use vm, change ng-model to data.searchFor
if (query == undefined) {
query = 'tech';
}
return query;
}
vm.getData = function () {
vm.users = [];
$http.get("/api/students/?category=" + vm.getSearch() + "&begin=" + vm.pageno + "&pageSize=" + vm.itemsPerPage).success(function (response) {
vm.users = response.data;
vm.total_count = response.total_count;
});
};
Your request id good, you need to optimize the sql query so you can get the right results. it should look something like this:
#begin INT = 0,
#pageSize INT = 10
SELECT *
FROM [TableName]
ORDER BY id
OFFSET (#pageSize * #begin )
ROWS FETCH NEXT #pageSize ROWS ONLY;
I am trying to get data to display in a table. I don't know what I am doing wrong, but when I get the data from my page it is an array of single characters. I could parse this myself but would prefer to know what I am doing wrong.
I have this php to get the data:
function BuildViewerCombo($autocomplete) {
$wholeNumberCombo = array();
$dbhandle = DB_Connect();
$result = QueryForward($dbhandle, SQL_WholeNumbersPartial($autocomplete));
while($wholeNumber = sqlsrv_fetch_array($result))
{
$wholeNumberCombo[] = array($wholeNumber['DocumentNbr'] => 'Number', $wholeNumber['DocumentRevision'] => 'Revision');
}
//close the connection
sqlsrv_close($dbhandle);
return $wholeNumberCombo;
}
Which is called from this page
<?PHP
include "Scripts/DB_Functions.php5" ;
include "Scripts/SQL_Viewer.php5" ;
$wholeNumber = $_GET['wholeNumber'];
echo json_encode(BuildViewerCombo($wholeNumber));
?>
Which gets loaded from this function
function toggleDropdown()
{
var wholeNumberData
var wholeNumber = document.getElementById('WholeNumber').value;
if (wholeNumber != '') {
wholeNumberData = GetData('wholeNumber', wholeNumber);
var table = document.getElementById("wholeNumberDropdown");
alert ('WN = ' + wholeNumberData.length);
alert (wholeNumberData);
for (var i in wholeNumberData) {
alert(wholeNumberData[i]);
}
}
else {
alert("Please enter a whole number.");
}
}
By calling this function:
function GetData(getType, param) {
var http = new XMLHttpRequest();
http.open("GET", 'ViewerWholeNumbers.php?wholeNumber=' + param, false);
http.setRequestHeader("Content-type","application/json");
http.onload = function() {
}
http.send('wholeNumber=' + param);
return http.responseText;
}
The data that gets returned is:
[{"SS3999":"Number","A":"Revision"},{"SS3999":"Number","11":"Revision"},
{"SS3999":"Number","11":"Revision"},{"SS3999":"Number","11":"Revision"},
{"SS3999":"Number","":"Revision"},{"SS3999":"Number","11":"Revision"},
{"SS3999":"Number","":"Revision"},{"SS3999":"Number","11":"Revision"},
{"SS3999":"Number","11":"Revision"},{"SS3999":"Number","A":"Revision"},
{"SS3999":"Number","11":"Revision"},{"SS3999":"Number","A":"Revision"},
{"SS3999":"Number","11":"Revision"},{"SS3999":"Number","A":"Revision"},
{"SS3999":"Number","":"Revision"}]
But alert ('WN = ' + wholeNumberData.length); returns 546 and when I try to loop through the array I get a single character for each element instead of the values.
First off, your associative array is flipped. You need to change
array($wholeNumber['DocumentNbr'] => 'Number', $wholeNumber['DocumentRevision'] => 'Revision');
to
array('Number' => $wholeNumber['DocumentNbr'], 'Revision' => $wholeNumber['DocumentRevision']);
You need that in order to access the elements of the JSON. Then, in your loop, you would use wholeNumberData[i].Number to get the number and wholeNumberData[i].Revision to get the revision.
Update:
As #jeroen pointed out, you need JSON.parse() to convert the return string to JSON. In your GetData function replace your return with this:
return JSON.parse(http.responseText);