Frustration with emberjs data transfering with its backend method as PHP - php

I tried to do these three simple things but I can not in a world to figure out in almost ONE MONTH already, one word---FRUSTRATION! Now I doubt if emberjs is really worth it...
I want to:
Get data from database with just a .php file and data will be in json format
NOTE: I did this, in other SO question I asked, so I will not repeat.
Now, the problem, how can I save those data in a "store" without ember data?
Is there any available tutorial on how php can connect with emberjs? I tried to read about its REST adapter, but seem it needs some type of JSON API. Do I need to develop a JSON API if I use pure PHP code as back end?
If anything part is not clear, please reply in comment! Thanks a lot.

Chen, to be honest it is very easy to handle data without ember-data . I have used it few times, some of which were related to building quite large front-end systems. Main reason, ember-data was not that stable at the time and did not inspire much confidence. The other reason is that as you will see it is pretty straightforward.
All you have to do is create a class (it is also nice to have a singleton ember controller) that will get data from the server and post data to the server. The data format should be JSON, to make all process easier and clearer. You achieve this by using simple ajax calls,
function retrieveData(callback){
jQuery.ajax({
url: *yoururl*,
timeout: ajaxTimeOut,
success: function(data){
/* here you store this data somewhere
it could be helpful to have a callback that you call so that this class/controller
is not coupled with specific logic*/
if(callback!=null){
callback(data);
}
}
});
}
The function for retrieving data can be called when the associated route gets called or from the controller of that route. The callback function passed to the previous class/controller will set the data retrieved to some properties of the controller, or it could even be its model. Simple example,
http://emberjs.jsbin.com/AsOcAbU/1/edit
js
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
/*model: function() {
return ['red', 'yellow', 'blue'];
},*/
setupController:function(controller,model){
this.controllerFor('myJSON').findJSONData(function(data){
controller.set('model',data);
});
}
});
App.IndexController = Ember.ArrayController.extend({
});
App.MyJSONController = Ember.Controller.extend({
findJSONData:function(callback){
var data = ['red', 'yellow', 'blue'];/*this will come from the server with an ajax call i.e. $.ajax({...})*/
if(callback){
callback(data);
}
}
});
hbs
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
{{#if model}}
<ul>
{{#each item in controller}}
<li>{{item}}</li>
{{/each}}
</ul>
{{else}}
loading ....
{{/if}}
</script>
In the context of complete application you will probably need to iterate the json data and create ember objects out of it. That is really simple as well thanks to ember,
http://emberjs.jsbin.com/oWetaDuH/1/edit
/*let's say you retrieve color objects from php*/
findJSONData:function(callback){
setTimeout(function(){
/*this will come from the server
with an ajax call i.e. $.ajax({...})*/
var data = [{color:'red'}, {color:'yellow'}, {color:'blue'}];
if(callback){
callback(data);
}
},2000);//mimic ajax call
}
/*and you need to use ember magic bindings, so you have your own objects to represent the domain model*/
App.MyColor = Ember.Object.extend({
color:null
});
/*then the code for retrieving will become*/
setupController:function(controller,model){
this.controllerFor('myJSON').findJSONData(function(data){
var myColors=[];
data.forEach(function(jsonColor){
myColors.pushObject(App.MyColor.create(jsonColor));/*this is all you need to create the ember object !!*/
});
controller.set('model',myColors);
});
}
and hbs
<script type="text/x-handlebars" data-template-name="index">
{{#if model}}
<ul>
{{#each item in controller}}
<li>{{item.color}}</li>
{{/each}}
</ul>
{{else}}
loading ....
{{/if}}
</script>
update
If it is required to pause routing until the model is resolved, then promises should be used as explained in the guides
http://emberjs.com/guides/routing/asynchronous-routing/
In this case, since jQuery ajax function returns a promise, the previous example could look like,
http://emberjs.jsbin.com/mogicira/1/edit
js
App.IndexRoute = Ember.Route.extend({
model:function(controller,model){
return this.controllerFor('myJSON').findJSONData(function(data){
var myColors=[];
data.forEach(function(jsonColor){
myColors.pushObject(App.MyColor.create(jsonColor));
});
return myColors;
});
}
});
App.IndexController = Ember.ArrayController.extend({
});
App.MyJSONController = Ember.Controller.extend({
findJSONData:function(callback){
return $.ajax({url:""}).then(function(data){
data = [{color:'red'}, {color:'green'}, {color:'blue'}];
if(callback){
return callback(data);
}
});
}
});

If you like ember & ember-data it should be for the less-code and code maintenance between other not less important concerns
If you feel comfortable with php, move your php code to a modern FrameWork for not reinventing the weel and in order to obtain similar benefits that ember done to your front-end
I'm developing an ember app feeded with Codeigniter http://ellislab.com/codeigniter and codeigniter rest service https://github.com/philsturgeon/codeigniter-restserver but I don't recommend you this combination
I my opinion you should try Laravel http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/ or directly go to Rails/Rails-API

Related

Interactive file processing in using PHP, jQuery and Ajax

I'm migrating an old MS-DOS Foxpro program to cakePHP, but in some part of the application process the user will have the possibility to load a text file and process it according to some business logic.
I worked the algorithm, and it's working fine, I programmed it in plain PHP.
But in some parts of the process the user must interact performing some tasks, in plain PHP it's possible to do it.
My question is:
How can I have an interactive file process on a MVC framework, since the controller had processed the data when it`s give the control to the view.?
jQuery-ajax could help?
What do you think?
Regards
Update
As Borislav Sabev pointed, I do this:
Create a file upload using using: jQuery Form Plugin
A PHP file parsing according the data structure on the uploaded file that returns to the client the parsed contents of the file in JSON.
Then the JSON data is sent for processing via ajax POST
$.each(data, function (i, fb) {
callAJAX(fb);
});
callAJAX just send the POST request
function callAJAX(fb){
$.ajax({
type: 'POST',
url: "proc.php",
dataType:"json",
complete: function(r,st){
},
success: function(r,st){
processError(r);
})
},
async: false
});
}
If there is a translation error, the PHP returns to the client an error message via JSON.
function proccessError(r)
{
$.each(r,function(i,d){
if (d['error'] == 1){
$.alert('Material not found in translation table','Error');
}
})
}
Now the big question:
When I open the $.alert dialog I want the user select the correct material via an autocomplete, but the code is no waiting for the user selection and pops another $.alert window. How can I tell jquery to wait to the user input an then continue with the processing?
BTW: this is the $.alert extension that I use:
$.extend({ alert: function (message, title) {
$("<div></div>").dialog( {
buttons: { "Ok": function () { $(this).dialog("close"); } },
close: function (event, ui) { $(this).remove(); },
resizable: false,
title: title,
modal: true
}).text(message)
.parents(".ui-dialog:eq(0)").wrap('<div class="error-w"></div>');
}
});
What #AD7six told you is completely right however your question is very vague.
What you seem to need is to provide an interactive (realtime?) way for a user to edit data after a files has been uploaded and processed?. If it is 'data arranged in rows' I can suggest some DataGrid - imagine this as a Web representation of your file's structure.
What you're trying to say with 'the view shows the result of a method or action on the controller' is that this case is in the normal HTTP (with MVC) flow:
Browser (user) initiates a request => Request is processed my Controller => Model is called (gets, saves or manipulates data) => Data is returned to Controller => Controller handles the data over to the View layer => The view layer renders, Controller returns the Response (the rendered view)
In order to do this thing interactively you will have to use AJAX (I propose AJAJ).
The overall paradigm in this case is that the above flow is iterated on every AJAX request. You can achieve this in many ways:
Use plain JavaScript and XMLHttpRequest
Use jQuery's XMLHttpRequest wrapper functions ($.ajax(), $.post(), $.get(), $.load(), etc.)
Some other JS lib's AJAX capabilities (MooTools for example)
Use an real-time JS app framework
This also heavily depends on the browsers (and versions) you need to support.
You will need to provide 'access' for the client-side via a controller or a full API. The best solution for an API would be REST. If this is an enterprise app I suggest you adhere to the Richardson Maturity Model.
If you don't need a fully-realtime app I'd go with jQuery AJAX or some other JS lib's AJAX.
The thing is that what you request as an answer is an overall explanation and that is why I am not going to provide code examples.
Cake has JSON views that you can use to return data.
The other option is an empty layout and a view that returns JSON encoded data like:
<?php echo json_encode($data);?>
Hope this helps. If anything ask.

How to display a 'live' count of total files uploaded?

I am looking to display the total number of files in a database. To clarify, say I had a website where people could upload pictures of their cars, and I wanted to display a live number of how many pictures there are, what would be the best way to do this? Javascript, php? A mix? I envision a div with a number saying "Total Pictures: x" and where x would be whatever the live total is. I plan on using MySQL to store all the data on the website. Is this even recommended to have something communicate with the server this much? Is there a name for displaying a live number? Thanks!
If you are thinking to use the AngularJS way, you could create a Poller service which polls every second (assuming your /counter.php returns json):
app.factory('Poller', function($http, $timeout) {
var data = { response: {}};
var poller = function() {
$http.get('/counter.php').then(function(r) {
data.response = r.data;
$timeout(poller, 1000);
});
};
poller();
return {
data: data
};
});
Then your controller:
app.controller('CounterCtrl', function(Poller, $scope){
$scope.counter = Poller.data;
});
And finally in your view:
{{counter.response}}
You can read more about $http
Set up a PHP script that queries the database and returns the total file upload count. After that, you can use JavaScript on the page to periodically call the server in a specified interval of time and fetch the count data from your PHP script. Using jQuery and GET, you can do something like this:
jQuery(function($){
setInterval(function(){
$.get( '/counter.php', function(fileUploadCount){
$('#counter').html( fileUploadCount );
});
},20000); // 20 seconds
});
In your HTML:
<p><span id='counter'>xx</span> files have been uploaded so far!</p>
Hope this helps!
How live do you want it to be? Just whenever someone updates the site it's going to have the new value or do you actually want it to update in near real-time?
If it's the latter you have to use Javascript against some kind of API that returns the amount of files in the database. I can't help you with that bit since you are using PHP, but it shouldn't be too hard. Just return some JSON looking something like
{ fileCount: 45020 }
Client-side you have a few options. You have the different javascript frameworks like AngularJS and EmberJS (and many more), as well as just 'plain old' javascript and frameworks like jQuery
The keyword is really AJAX, even if that is just a sort of buzzword for using javascript to make websites dynamic.
I am a fan of using AngularJS because it's easy, but I'll try to give you some pointers for using jQuery first. Note that I have not used jQuery in years now.
The jQuery way
jQuery has a function called jQuery.getJSON(), and according to the documentation you can use that function something like this:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON( "http://example.com/api/fileCount.json")
.done(function(data) { console.log(data) })
.fail(function() { console.log( "error" ); })
.always(function() { console.log( "complete" ); });
So this means we can call an endpoint and fetch some data using jQuery.
Here is a link to a tutorial about the basics of jQuery by the way.
jQuery makes us able to do things like this:
<div id="divTest1"></div>
<script type="text/javascript">
$("#divTest1").text("Hello, world!");
</script>
When that is executed the div with id "divTest1" will contain the text 'Hello, world!'.
That sounds like something we could use here!
Javascript also has this really nice function called setTimeout(), which allows us to make it call a function later.
This describes how to use jQuery with setTimeout()
As you can see it also shows us jQuery.documentReady(), which is an event that fires when the website is finished loading, so it is a good place to put code we want executed.
The example below shows how to use jQuery to hide a div with id=div after 3 seconds.
jQuery(document).ready(function () {
setTimeout( "jQuery('#div').hide();",3000 ); //hide a div after 3 seconds
});
Combining these things you should be able to make a repeating call that fetches data from your server and then updates a div or another element with the data you have fetched.
Just create a function which uses jQuery.getJSON() to fetch data, and then at the bottom of that add a setTimeout call to run itself in X seconds (however often you want it to update).
In jQuery.documentReady() you call that function the first time the document loads.
And in the .done() bit of the getJSON() call you add the data you got from the server to your div with whatever html you want. I showed you how to use $("#divTest1").text(), but there is also a .html() which acts the same but you should use it to add html to a element.
The angular way would be to use AngularJS's $http to do the same thing, but I wouldn't recommend learning AngularJS until you have a bit of a better grasp on Javascript.
When you do though, I highly recommend it. It's a much better approach than using jQuery.
You can read about AngularJS here
I hope this helps!

Communicating with server with Backbone.js

I'm a newbie web developer diving into Backbone for the first time. One major question I've been grappling with (actually spending a lot of the last 2 days researching to no avail) is how exactly Backbone communicates with the server.
In my previous projects, I've been able to fetch data from my database using PHP and jQuery's $.getJSON method. I'm also able to do this when I use Backbone (ex. myCollection.url = "todos.php"). However, in every single tutorial, documentation, example code I've looked at, the url for the collection is always set as a directory and the urlRoot is directory/id (ex. myCollection.url = "/todos" and myModel.urlRoot = "/todos/5".
My question is how exactly is this managed? It seems a lot cleaner than the traditional way I was doing by adding GET parameters to my calls. At first I thought this was routing, but that seems to be only related to setting browser history and stuff. Some of the source code I've looked at uses SLIM PHP and Rails (neither of which I've used) but I have no clue how any of the parts fit together.
Backbone has its own api for communicating with server, such as fetch, save, destory.In fact, these methods do the same things with jQuery's $.ajax. For example, you use backbone's fetch in this way:
var UserModel = Backbone.Model.extend({
url : "rootURL/user",
});
var user = new UserModel;
user.fetch(
data:{
userId : 1, //the webservice will be: rootURL/user?userId=1 GET;
}
success:function(model, response, options){
//callback
},
error:function(model, response, options){
//callback
},
);
But you can also use the same way as in the jQuery to communicate with server in backbone's application.For example:
var UserView = Backbone.View.extend({
render: function(){
//do something
}
getUser: function(userId){
$.get("rootURL/user",
{ userId : userId},
success:function(data){
//callback
}
);
}
});

How can i change multiple portions of a webpage with ajax onclick?

In my website I will have a "browse catalogue" button, which, onclick will change several elements of the page to display the catalogue element. I dont want a full page reload because several elements such as the nav bars and news feed will stay the same.
My question is how can i change several different divs with ajax onclick?
Essentially im not sure how to do place several different components in different divs across a page.
And i know there's a limit on simultaneous ajax calls, so im sure the proper way to do it wouldnt be to make a unique ajax call for each of my divs.
A little guidance would be great.
Using jQuery, you can get an json array of elements for each block that needs to be updated:
In your html page:
$.get("page.php?id=42",
function(result){
$('#title').text(result['title']);
$('#description').text(result['description']);
$('#price').text(result['price']);
}, "json");
In page.php:
$result = array('title' => 'foo', 'description' => 'bar', 'price' => 3);
echo json_encode($result);
header('Content-Type: application/json');
die();
I'm not sure if the right decision will be to send several ajax requests. Just create a request with unique attribute value, in so shape that server will know which blocks you need. On server side all required blocks concatenate in json object, and return it to client. After just parse object on blocks that should be. For example
$.ajax({
url : 'http://your.server.doment',
data : 'block[]=1&block[]=7&block[]=15',
type : 'post',
dataType : 'json',
success : function (object){
for( el in object) { $('#block_'+el).html(object[el]); }
}
});
you can use json
example
php request ajax
$div1="<table><tr><td>x</td></tr></table>";
$div2="<table><tr><td>x</td></tr></table>";
$div3="<table><tr><td>x</td></tr></table>";
$json = '{"div1":"'.$div1.'","div2":"'.$div2.'","div3":"'.$div3.'"}';
return $json;
uses jquery
$.ajax({url: 'ajax/test.php',
success: function(data) {
var obj = JSON.parse(data);
$("mydiv1").html(obj.div1);
$("mydiv2").html(obj.div2);
$("mydiv3").html(obj.div3);
}});
if you have a error in the parce function
replace spaces
example
$arr =array("\n","\t");
$div1= str_replace($arr,"",$div1);
Practically, ten or more elements updated in parallel on the page (each by a separate ajax) will not make such a big difference (unless you can test it with your website deployed into productive environment and prove I am wrong).
Nonetheless, if you wish to compact all the data exchange to one single request/response ajax call - it is very well possible but does require certain flexibility on the server side (see http://php.net/manual/en/function.json-encode.php).
I.e. one of the possible solutions is to produce json response on the server side, that generates a key-value pairs (JSON - javascript {} object) with keys being id of your elements and values being (new) html.
There are tons of ajax JS frameworks as jQuery, prototype, dojo, etc. (I will pick jQuery for this one).
Ajax request
$.ajax({
...
})
See http://api.jquery.com/jQuery.ajax/
Server response
// Assume we got
// var data = {key1:'html1',key2: 'html2'};
// Ajax handle can look like
success(data) {
$.each(data, function(key, val){
//console.log(key, val);
// Do some checks here.. But key should indicate #id of html elements
$(key).empty().append(html);
});
}
This is a basic outline but should keep you going into the right direction.

PHP / AJAX Application structure

I'm working on a PHP / AJAX application and it's quickly becoming unmanageable!
The application is designed to work much like a a desktop application so almost every user action results in an AJAX call.
For every one of these actions I have some jQuery that posts the data to my PHP script and runs a corresponding PHP function that handles the server side actions.
That means in my jQuery file i'll have something like this:
$('.delete-project').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_project
});
$('.delete-user').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_user
});
$('.delete-keyword').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_keyword
});
I'm sure there is a better way of doing things, but how is it generally done to avoid lots of similar code? The above actions could possible rolled into one 'delete' ajax request which posts the item type and a database ID but a lot of my functions post different data and require different parameters so wouldn't fit so neatly under one jQuery handler.
I've tried finding some resources on how an AJAX application should be put together but all I can find is beginner tutorials on making AJAX requests etc, not how to write a scalable AJAX application.
Just to be clear I know how AJAX works, I'm just trying to find the best way of implementing it in terms of reducing the jQuery and PHP needed where possible.
Are there any good resources that deal with this sort of thing?
You can roll all those into one delete function by using attributes in HTML, for example:
$('.delete').on('click', function(){
var delete = $(this).attr('data-delete');
// Ajax request to http://myapp.co.uk/ajax/delete_{delete}
});
Then your HTML would be something like:
Delete
More information on data-attributes
Not sure if this would help but you could create some functions to reduce your code as it grows. For starters you could prevent duplicating of the ajax call by putting the jQuery .ajax function in a custom wrapper function of your own. For example:
function ajaxGet(myUrl, queryString, successCallback, errorCallback) {
if(queryString) myUrl+= "?" + queryString;
$.ajax({
url: myUrl,
type: "GET",
data: null,
success: function (res) {
if(!successCallback) return;
else successCallback(res);
},
failure: function (res) {
if(!errorCallback) return;
else errorCallback(res);
}
},
By creating a wrapper function, you can pass in the needed data without duplicating the $.ajax call code over and over in each of the click functions. You can also create a similar function for an ajax call using post. You could then dynamically build the click functions to further reduce your code:
function buildClicks() {
setupClick([url], [data], [success], [error], [$(elem)]);
setupClick([url], [data], [success], [error], [$(elem)]);
setupClick([url], [data], [success], [error], [$(elem)]);
}
//Setup clicks for each button or link
function setupClick(url, data, success, error, elem) {
elem.click(function () {
ajaxGet(url, data, success, error);
});
}
In this example I'm assuming your using a "GET" and adding a query string. You could easily adapt this to pass, a JSON formatted object for example, using a custom "POST" function. In that case [data] would be an object not a query string.
Sorry this code isn't the clearest. Let me explain it a little more. The buildClicks function would allow you to setup multiple click events on different elements by passing in the required data. I'm not sure if you are passing any data, but the above functions would allow for it. By dynamically creating the clicks you can avoid duplicating the .click code over and over. Just call the buildClicks function on document ready as such.
$(document).ready(function () { buildClicks(); });
NOTE: The success and error callbacks are functions that will be executed when your call either completes successfully or errors out. If you do not wish to use these they can be ommitted or null can be passed in. Make sure if you do pass in functions that you leave off the "()" on the end of the function name. Otherwise the functions will be executed prior to the success or failure of the ajax call. For example:
ajaxGet("http://testurl.com", null, ajaxSuccess, ajaxFailure);
ajaxSuccess() {
}
ajaxFailure() {
}
You could set an ID attributes to that buttons and a class like submit-button.
Then hang a handler on that $('.submit-button') while using an ID attribute value to define the URL to call, like that:
$('.submit-button').on('click', function(){
$action = $(this).attr('id'); //lets say the ID's value is 'delete_project'
$url = 'http://myapp.co.uk/ajax/' + $action;
// Ajax request to http://myapp.co.uk/ajax/delete_project is done
});
Anyway any web application that tends to be like a desktop one is only a bunch of JS and few HTML with some PHP behind... That is always badly maintanable...
I used [extJs][1] once for this, which led to using only jQuery and their modules while no (or just a minimum of) HTML was needed to write...
Not a copy-and-paste-solution, but maybe you find some more ideas how to build a scalable client-server application when looking for how REST APIs are built. I find REST a very good structure to keep a clear server-side API when building such apps, and i'm sure there are tutorials around how to do the corresponding client-part cleanly too.
In my application I do quite a lot of ajax calls too. I found that the easiest way to do things was to create myself a wrapper for all ajax calls such as:
var MySite = function()
{
AjaxWrapper : function(type,url,data,callback,noloading)
{
$.ajax({
type: type,
url: url,
data: data,
success:function(json)
{
if(json.status === true)
{
if(typeof callback === 'function')
{
callback(json);
} else {
// A generic success handler
}
} else {
// An error handler
}
}
});
};
}();
then you'd call it like:
MySite.AjaxWrapper("GET", "somehref", {}, function(json)
{
// json has the result of your json callback
// you could also make this a separate function
// or not have it
});
this let's you call your ajax on just about anything you want. You could then use something like data attributes, or just the standard href for anything that requires ajax and add an event to all links that pass through this function. Or, if you wanted some to do certain things just make the callback function different for those.
I'm finding this hard to explain, but this is what I've used for a couple of ajax-rich projects and it makes things so much easier!
For an example for your case you could then use something like:
$('a[class|="delete"]').on("click", function()
{
MySite.AjaxWrapper("POST", $(this).attr("href"), {param:number1}, DeleteHandler);
});
The way I would do this would be to have a single function for all actions:
$('.actions').on('click', function (e) {
e.preventDefault();
var action = $(this).data('action'),
id = $(this).data('id');
$.get('/local/handler.php', {
'action': action,
'id': id
}, function () {
// Callback stuff here
});
});
And HTML:
Delete Project
Delete User
Delete Keywork
And the PHP file should have if statements based on the action parameter that performs the requested action.
EDIT:
This way your not limited to just delete actions, so you can scale your app in the future.
Also, If the different actions become a large list (e.g. deletes of many kinds, updates, adding), I would create a separate PHP file for each action and include them in one master file. This will allow for easy scaling.

Categories