convert from PHP to JSON file - javascript

I am a Laravel learner. What I am trying to learn now is to send a JSON file from a back end into the front-end, so that I will use this JSON file to draw a graph.
In my model, I write a function that will extract the values and time stamp created_at. Here is a piece of code that will return the google page speed value associated with a single website and the time stamp.then I want to use JS to draw the graph where the vertical value is the google page speed and the horizontal is the time stamp created at.
Anyone who can help me? Do I need to change the return value to an array?
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Notification;
use App\Status;
class ChartController extends Controller
{
public function speedHistory(){
$o_status = Status::where('name','speed')->first();
$o_response = $this->statuses()->where('status_id', $o_status->id)
->select('values AS value', 'created_at AS timestamp')->orderBy('created_at','DESC')->get();
if($o_response){
return response()->json($o_response);
}
// return an empty json array instead of false
//return false;
return response()->json(array());
}
}
and trhe route is
Route::get('json','ChartController#speedHistory');
keeps complaining the methods is not defined. this is my model
lass Notification extends Model
{
protected $fillable = ['id','website_url','email','slack_channel','check_frequency','alert_frequency','speed_frequency','active'];
public function statuses(){
return $this->belongsToMany('App\Status')->withPivot('values')->withTimestamps();
}

You could use the json() method on response().
The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function:
$array = ['data'];
return response()->json($array);
Laravel Documentation (json-response)

In your function:
public function speedHistory(){
try{
$o_speed = Status::where('name','speed')->first();
$o_response = $this->statuses()->where('status_id', $o_status->id)
->select('values', 'created_at')->orderBy('created_at','DESC')->get();
if($o_response === null)
//You can use this to go in catch: "throw new Exception();" or "return false" if you want
throw new Exception();
// Returns a json to be consumed in ajax
return response()->json(['status' => 1, 'code' => 200, 'message' => 'Your message', 'value' => $o_response->values, 'timestamp' => $o_response->created_at], 200);
}catch(\Exception $e){
return response()->json(['status' => 0, 'code' => 400, 'message' => $e->getMessage()], 400);
}
In your ajax you consume this way:
var request = $.ajax({
// Here's your route of speedHistory
url: "YOUR_ROUTE",
type: "GET",
dataType: "json"
});
request.done(function(response) {
if(response.status == '1'){
$("#youDiv").html(response.value + ' - ' + response.timestamp);
}
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});

To improve on my answer, you will need to return 'response()->json()' which will change the content type to json, essentially making the response a so called "JSON file".
Can you try this? I think you are trying to get values and created_at from a collection which should not work. I assume you use L5, see Danis Abols comment otherwise.
public function speedHistory(){
$o_status = Status::where('name','speed')->first();
$o_response = Notification::where('status_id', $o_status->id)
->select('values AS value', 'created_at AS timestamp')->orderBy('created_at','DESC')->get();
if($o_response){
return response()->json($o_response);
}
// I would return an empty json array instead of false
//return false;
return response()->json(array());
}
Update: added Notification:: based on comments from op

Try this
return json_encode(array('value' => $o_response->values,'timestamp' => $o_response->created_at));

Related

Send variables in url and object in Body using Fetch

I'm working with my project where using Asp.net with c# and Javascript.
I have my controller set up with c# where it accepts an object, and two additional variables. It is a HttpPost request, and it works fine until I added the additional variables. I've used console.log in my fetch json function to check that i truly get the desired values, which I am.
This fetch works fine with postman!
I've also tried swiching places on the Rented object, so that it is in the last position, if the Body of fetch was sent in last aswell, but it did not work.
This is what I get back when calling the function in my chrome browser:
https://localhost:44363/rent/save?movieId=2&maxRents=3 Status = 400
Feels like I'm missing something very basic here, maybe you can't send both variables and body at the same time with a request?
Here's the controller code:
[HttpPost("save")]
public ActionResult<Rented> SaveRent(Rented newLoan, int movieId, int maxRents)
{
var amountOfRent = _appDbContext.Rents.Where(m => m.MovieId == movieId);
if (maxRents <= amountOfRent.Count())
{
_appDbContext.Rents.Add(newLoan);
_appDbContext.SaveChanges();
return newLoan;
}
else
{
return BadRequest();
}
}
And here's the Fetch function:
function addToStudio(element) {
var movieId = element.id;
var studioId = element.value;
var maxRents = element.name;
var newId = Number(movieId);
var newStudioId = Number(studioId);
console.log(maxRents);
fetch('https://localhost:44363/rent/save?movieId=' + movieId + '&maxRents=' + maxRents, {
method: 'POST',
body: JSON.stringify({
studioId: newStudioId,
movieId: newId
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.catch(err => console.error("response-error", err))
.then(response => response.json())
.then(json => console.log(json))
.catch(err => console.error("json error", err))
container.innerHTML = `<h1>Saved</h1>`
}
I can see a couple of problems here:
You are using both the body of the request and in the URL query.
You're missing some important attributes in the control method signature .
I personally always try to use a single approach (either body or URL query). I find that it keeps the code more readable and is less bug-prone.
First of all, decide how you want to pass the data:
Through the request body
In the URL query
Mixed approach
Then write your methods accordingly.
In the body
The easiest approach is encapsulating your information in a .Net object and Jsonify its fields in the JavaScript:
public class RentDetails
{
public int MovieId {get; set;}
public int MaxRents {get; set;}
public Studio {get; set;} // you can also use objects, deserializing the Json will fill them as well.
}
Then you want to specify in the signature of your method that you are receiving a RentDetails in the body of the request.
[HttpPost("save")]
public ActionResult<Rented> SaveRent([FromBody] RentDetails rentDetails) { ... }
And lastly, you want the Jsonified body to reflect the object that should be received (pay attention to field names):
const request = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
movieId : movieID,
maxRent : maxRent,
studio:
{
// nested fields for nested objects
}
})
};
If you follow these steps, your controller will automatically deserialize the json in the body to the object and it will be ready for you to use.
In the URL Query
This is easier to handle but might grow to be messy.
Concatenate the fields in the javascript how you were already doing:
const link = baseLink.concat('?movieId=', movieId, '&maxRent=', maxRent, ...);
const result = await fetch(link); // no request is needed here, you already have all you need.
And then access those fields from the controller:
[HttpPost("save")]
public ActionResult<Rented> SaveRent() //<- no parameters are needed here
{
var allUrlKeyValues = HttpUtility.ParseQueryString(Request.QueryString.Value);
var movieId = int.Parse(allUrlKeyValues["movieId"]);
var maxRent = int.Parse(allUrlKeyValues["maxRent"]);
....
// as you see you can only pass strings in this way
}
Mixed Approach
Of course you can opt for a mixed approach, just use a combination of the code above.
Note that the simpler, the better ;).

Error with Json value from controller to use in view, Laravel 5.6

I can't convert Json value that i got from my controller to the proper javascript readable value.
This is my controller
$room = Room::
select('id', 'name', 'capacity', 'status')
->get();
$this->rooms = json_encode($room);;
return view('admin.rooms.index', $this->data);
on the view, {!!$room!!} gives
[
{"id":1,"name":"room1","capacity":4,"status":"dirty"},{"id":2,"name":"room2","capacity":5,"status":"clean"},{"id":3,"name":"room3","capacity":5,"status":"clean"}
]
so i get json value i need..
when i use {!!$room!!} in my script
function loadResources() {
$.post( "{!!$rooms!!}",
{ capacity: $("#filter").val() },
function(data) {
dp.resources = data;
dp.update();
});
}
Uncaught SyntaxError: missing ) after argument list
thats the error i get..
if i create a file and put json value in a file
function loadResources() {
$.post( "room.json" ,
{ capacity: $("#filter").val() },
function(data) {
dp.resources = data;
dp.update();
});
}
Everythins works fine..
i tried JSON.parse(), to make the value javascript readable but failed.
How can i use that json value in my javascript code
Do not json_encode the result set.
Pass the entire object to the view like this:
$room = Room::
select('id', 'name', 'capacity', 'status')
->get();
return view('admin.rooms.index', $room);
Then in the view what you can do to retrieve the value from the above passed data is:
{{$room->id}}
try encoding the rooms array in the view i.e in javascript section. Then pass it to loadResources function.

How to avoid wrapping PHP result into another array?

The following is the php code:
<?php
session_start();
if(isset($_SESSION["loggedUser"])) {
generateAndProvideData($_SESSION["loggedUser"]);
} else {
//error handling
}
function generateAndProvideData($loggedUser) {
$connection = establishConnectionToDatabase();
$UserData = retrieveUserData($connection, $loggedUser);
echo json_encode($UserData);
}
function retrieveUserData($connection, $loggedUser) {
return $connection->query("
SELECT name, vorname, email
FROM benutzer
WHERE id = '".$loggedUser."'
")->fetchAll(PDO::FETCH_ASSOC);
}
function establishConnectionToDatabase() {
try {
$connection = new PDO('mysql:host=localhost;dbname=------------','------','-----');
} catch(PDOException $e) {
echo $e->getMessage();
}
return $connection;
}
?>
On the scriptside, it was called like this:
function populateUserData() {
$.post('../include/getUserDataForBenutzerprofil.php', {
//nothing to transmit
}).then((data) => {
data = JSON.parse(data)
console.log("data from getUserDataForBenutzerprofil.php is ", data)
//$('#name').val(data.name)
})
}
Now, as far as I understand php, it creates an array with the names of the columns being the keys to the respective values.
However, the array that is returned to the front-end seems to be multidimensional, see the following output:
[{"name":"----","vorname":"-----","email":"---.---#example.de"}]
Why is that? And is there any way around it?
This way, I always have to address the numerical index "0" first, and then in the second index write out the respective associative key. While this isn't a major issue, it feels rather "unclean", since this is neither necessary nor was it intended.
According to https://www.w3schools.com/js/js_json_parse.asp
When using the JSON.parse() on a JSON derived from an array, the method will return a JavaScript array, instead of a JavaScript object.
and
As long as the response from the server is written in JSON format, you can parse the string into a JavaScript object.
so try changing your response format to json.
function populateUserData() {
$.ajax({
type: "POST",
url: "../include/getUserDataForBenutzerprofil.php",
// data: {},
dataType: "json" //<-- this
}).then((data) => {
data = JSON.parse(data)
console.log("data from getUserDataForBenutzerprofil.php is ", data)
})
}
Assuming the response is a valid JSON string of course.

Parsing json with php and javascript

I'm pretty confused and every way I've tried I keep getting internal error 500.
I'm trying to parse THIS json using PHP and return it to the client side.
inventory.php
/**
* Fetches users inventory.
*/
$userId = $_GET['userId'];
$inventoryUrl = 'http://steamcommunity.com/id/' . $userId . '/inventory/json/730/2/';
if ($userId) {
$url = file_get_contents($inventoryUrl);
$json = json_decode($url);
print_r($json);
}
And with jQuery I'm trying to fetch that object and parse it so I can insert it into html.
$.when(getUserInventory('koraktor')).done(function(data){
var inventory = data;
var selectItemsElem = $('#select-items');
console.log(inventory);
//console.log(inventory);
});
function getUserInventory(userId) {
var inventoryUrl = 'inventory.php';
return $.ajax({
url: 'inventory.php',
data: {userId: userId},
})
.done(function(data) {
return data;
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
}
});
In console it shows:
I need to parse $object->rgInventory->rgDescriptions
I'm just not sure how though.
SO my question is, how do I correctly parse this object so I can use a for loop and how would I use the for loop so I can insert each item into html?
You can enumerate the properties of the rgInventory part of your object. These are your items.
for(var item in inventory.rgInventory) {
if (inventory.rgInventory.hasOwnPrioperty(item) )
console.log(item.id)
}

pass collection of objects through http post in angular js

I have pass a collection of objects through http post in angular js.
The code is as follows:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data.ContentId, { Selected: true }); // I could able to get all the selected objects here, No problem with it
var jsonData = angular.toJson(contents); //It is not able to convert to Json if there are more than 5 records
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent?jsonData=' + jsonData, {});
promise.success(function () {
window.location.reload();
});
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(string jsonData)
{
var contents = JsonConvert.DeserializeObject<List<ContentNodeInWorkFlow>>(jsonData);
foreach (var content in contents)
{
_contentService.PublishContent(content.ContentId, userId);
}
}
}
The above code works fine if there are 5 records or less. If there are more records, I could able to get all the selected record
objects in the variable 'contents'. But the problem is occuring when converting to Json for all those objects. I
have about 500 records to pass through. How can do I it?
There is no specific reason to convert to JSON data. I just need to extract the ids of all the selected items. I have modified the above code as below:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var abc = [];
angular.forEach(contents, function(content)
{
abc.push(content.ContentId); // got all the ids in the array now
});
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,{contents : abc});
promise.success(function () {
window.location.reload();
});
}
I have just took an array and pushed all the content ids into it. I could able to see all the ids in the array now. I tried to pass the array as above.
How to retrieve those array in the code behind.
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(int[] abc)
{}
I do not see any values obtained under int[] abc. What will be the datatype for the parameter in the method call above.
You need second argument of $http.post method. You have to send such data by POST requests, not in query of url. You can put some data into body of the post request.
You need this:
var postBodyWithHugeAmountOFData = {data: [1,2,3,4,5...500]};
$http.post(url, postBodyWithHugeAmountOFData).success(function () {});
Also, you must be ready to handle this request in your backend.
is there any specific reason u want to pass this data as a JSON?.
if u r using Web API in that case u can pass the object as it is but only make sure that collection in web API method contains all the property in javascript collection
Thank you for all your posts. It's working fine without converting to Json. The code is as below.
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,contents);
promise.success(function () {
window.location.reload();
});
}
and the signature would be
public void CmsPublishApprovedContent(List<ContentNodeInWorkFlow> abc)
{
}

Categories

Resources