Ok, So I'm using AJAX to pull some information from my MYSQL database and put it onto the screen. The thing is I cannot understand JSON for the life of me. Can you suggest any tutorials or anything that will help?
I mean I get that I can encode my query via JSON but I guess it's the javascript side I do not understand.
Here's my quick tutorial:
JSON is a means for expressing data for arrays, objects, and their contents. It has nothing to do with object behaviour (methods).
<?php
class Test {
public $hello = 'hello';
public $something = array('hello1', 'hello2');
public __construct() {
}
public void printHello() {
echo $this->hello;
}
}
?>
This class would in JSON would look like:
var obj = {
"hello": "hello",
"something": ["hello1", "hello2"]
};
As you can see, JSON is similar to maps in a lot of languages (key/value pairs). You can also see, that only data is represented. JSON is also shorthand for JavaScript builtins. For example, this previous object can be written in JavaScript like so.
var obj = new Object();
obj.hello = "hello";
obj.something = new Array("hello1", "hello2");
Hope this gives you a little idea of what JSON is about.
First, read this: http://www.json.org/js.html
Then, practice with this: http://jsonlint.com/
You can read about using JSON in JavaScript at the Mozilla docs.
Maybe this short example will help you: http://www.factsandpeople.com/facts-mainmenu-5/26-html-and-javascript/89-jquery-ajax-json-and-php.
jQuery docs - getJSON()
How to use JSON (updated with example)
http://www.javascriptkata.com/2009/09/16/how-to-use-json-updated-with-example/
Related
I've a json response like following:
Now I want to parse the images object and get the front_image particularly. I've tried:
//after json_decode($claim)
$front_image = $claim->images->front_image; // let's say the response is stored in $claim
$front_image = $claim->images[0]->front_image;
How can I get all the properties of images and store them into different variables?
None of them worked.
First of all, if you are using Laravel, post your full controller...
Second, please, read the documentation as you do not need json_decode ever again... You are not using the framework then...
Your code should be like:
public function show(Request $request)
{
// After validating input with Validator or FormRequest
$front_image = $request->input('claim.images.front_image');
$front_image = $request->input('claim.images.0.front_image');
// Depends on how your data is structured, maybe you will need a loop
}
You can get images with php json_decode() function:
$claim= json_decode($jsonstring);
print_r($claim->images);
Replace $jsonstring with the actual json input.
I am using Laravel routes to build a RESTful API. I am routing to a Controller. In it, my function "store()" (my post function) should be getting a JSON input and I'm testing it by simply returning it. I seem to be able to see the data being passed in by doing Input::get('data') but I can't do a json_decode on that. The value of the json_decode is simply null. Can anyone help me get a working example of POSTing to a route with JSON data and accessing the data?
Here's what I have:
Route
Route::post('_api/tools/itementry/items', 'ItemEntryController');
Controller
class ItemEntryController extends BaseController
{
//... other functions
public function store()
{
if(Input::has('data'))
{
$x = Input::get('data');
$data = json_decode($x);
var_dump($data);
}
}
}
I'm using a REST tester client to submit a post with the following Query string parameters:
Name: "data"
Value: { itemNumber:"test1", createdBy:"rsmith" }
This ended up being a really stupid problem. I was doing everything right, except my JSON that I was sending in the test client was formatted incorrectly. I forgot to add quotes around the key strings.
So, instead of doing { itemNumber:"test1", createdBy:"rsmith" }
I needed to do { "itemNumber":"test1", "createdBy":"rsmith" }
Now it works.
My Backbone app is communicating with a REST API built on top of MongoDB, so my objects' "natural" ids are really MongoIDs. When serialized into JSON, they look like:
"_id":{"$id":"505099e998dee4db11000001"}
The Backbone documentation mentions that you can specify another name than id for your Backbone model's id attribute (using idAttribute), however, as MongoIDs' string representations are nested, just using idAttribute: '_id' doesn't help in consuming JSON directly.
Is there a way around this, other than rewriting attributes on the server side?
Update:
Here's what I'm doing server-side:
$m = new Mongo();
$posts = $m->mydatabase->posts->find();
$out = array();
foreach ($posts as $post) {
$out[] = $post;
}
echo json_encode($out);
I know I could do something like $post['id'] = (string) $post['_id']; unset($post['_id']); but it is precisely what I'm looking to avoid!
This sounds like a good example for parse().
Since your Mongo JSON ends up sending:
"_id":{"$id":"505099e998dee4db11000001"}
Why not use the Backbone parse to properly namespace the incoming data?
parse: function(response) {
response.id = response._id['$id'];
delete response._id;
return response;
}
Or something like this. Similarly, since Backbone will be sending the id as JSON with 'id', your server might take that and "translate" it the other way.
If you want to use a different id attribute, _id, you would just replace the above parse with this code:
idAttribute: '_id',
parse: function(response) {
response._id = response._id['$id'];
return response;
}
Whatever works best for you. :-)
It's better to do the conversion in the browser so you move the computation off from the server. So you'd want to create a base MongoModel, and then you can extend from MongoModel instead of Backbone.Model.
MongoModel = Backbone.Model.extend({
// this handle conversion between the mongo's _id and backbone id
// this is best done on the client side to alleviate server load
//_id : { "$oid" : ... } <--> id
parse : function (response) {
response.id = response._id.$oid;
delete response._id;
return response;
},
toJSON : function () {
var
json = Backbone.Model.prototype.toJSON.apply(this);
json._id = {'$oid':json.id};
delete json.id;
return json;
}
});
Looking at various suggested options I found the easiest would be to do what you want to avoid. (Using parse does work though)
$m = new Mongo();
$posts = $m->mydatabase->posts->find();
$out = array();
foreach ($posts as $post) {
// populate an id field
$post['id']=$post['_id']->{'$id'},
$out[] = $post;
}
echo json_encode($out);
Keeping $post['_id'] if you want your model to send it back when syncing.
I prefer correcting the API as more clients might want to connect to it.
In Ruby I'm able to do the following:
items.find.to_a.map do |item|
frombsonid(item)
end.to_json
def frombsonid(obj) obj.merge({'_id' => obj['_id'].to_s}) end
and when you get the data back, you can convert the string to BSON::ObjectId
def tobsonid(id) BSON::ObjectId.fromstring(id) end
So the idea is to replace _id in each item with a string version of BSON::ObjectId
In backbone you can add
idAttribute: "_id",
In PHP you will use different syntax and methods, but I believe it's quite possible to replicate this.
Your PHP code is the REST API that Backbone will interact with, so it should handle the abstraction of Mongo's complex _id property to the simple id string you're looking for. That is definitely the API's job.
Backbone, or any other consumer of your API, should NOT know anything about Mongo or _id.
Why?
Because if you were to switch from Mongo to some other Db where there is no _id, then your API is still good because all that was ever exposed was id, which is super generic. So you're original idea was actually the best idea (although you'd want to abstract that piece of code into something that can be reused for all models, not just posts).
I'm trying to develop a Flex Mobile / PHP application, and I'm running into some trouble with the AsyncToken... Does it not just return a basic string?
For example... I'm wanting to just return a simple string result from my request - right now, it's going to return a basic output string from the method that's implemented. The backend part works (PHP), I've done all of that... It's this that's giving me some problems:
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function button_clickHandler(event:MouseEvent):void
{
loginResult.token = user_service.login();
loginResult.token.addResponder(new AsyncResponder(onResult,onFault));
}
public function onResult(event:ResultEvent, token:Object):void
{
// what would i do here??
}
public function onFault(event:FaultEvent,token:Object):void
{
txtResult.text = event.fault.faultDetail;
}
It's pretty straightforward - any suggestions, or recommendations would surely help! Thank you!
Easy enough. The ResultEvent#result property contains the value returned by the remote service. All you need to do is cast it to the right type (since it is an Object by default).
For instance, handling your service method that returns a String:
public function onResult(event:ResultEvent):void {
var s:String = event.result as String;
}
Same goes for other types:
var a:Array = event.result as Array;
Or even more complex custom classes:
var instance:MyClass = event.result as MyClass;
Note that this last example will only work with AMF remoting; you have to have the same class definition on the client side and on the server side; and you have to let them know of each other's existence by using the [RemoteClass(alias="net.riastar.MyClass")] metadata tag on your AS class definition. How you have to handle this on the server side depends on the language used there.
I have a php file that creates a json output. my problem is that i will need lots of functions that return json data. For example:
i will need to fetch a list of all customers in a given db;
I will need to fetch all vehicles from a given customer;
i will need to fetch all data from a given vehicle
and so on. At this point i can have all this working if each function is in a separate php file. The complexity of this is only going to increase and i dont want to have lots of files cluttering the file system. Is there a way around this? any practical example would be appreciated
Sure. If you have one function for each type of action, like this:
function action_hello_world() {
echo "Hello, world!";
}
function action_hello() {
echo "Hello, {$_GET["name"]}!";
}
Then create an array of valid actions:
$valid_actions=array("hello_world", "hello");
Then we have a GET parameter called action:
$action=$_GET["action"];
We check to make sure it's valid...
if(!in_array($action, $valid_actions)) {
die("Invalid action.");
}
Then we call the correct function:
$function_name="action_$action";
$function_name();