I used AngularJS to make an app for grading students. It works perfectly 90% of the time, but every now and then, it doesn't record the data. The grade given or other change made will be reflected in the DOM, but disappears when the page is refreshed.
I use an angular service to send data to a PHP file which sends it to a JSON file.
The service is set up like this:
app.factory('studentList', function($http) {
var studentService = {};
studentService.getInfo = function() {
var promise = $http.get('../data/studentList.json').then(function(response) {
return response.data;
});
return promise;
};
studentService.sendData = function(data) {
$http.post('../data/studentData.php', data)
.success(function (data, status, headers, config) {
console.log(status);
})
.error(function (data, status, headers, config) {
console.log(status);
});
};
return studentService;
});
When I give a grade or change student info, I call the sendData() function defined in the service. This sends it to the PHP file which looks like this:
<?php
$data = file_get_contents("php://input");
$file = "studentList.json";
file_put_contents($file, $data);
?>
I've used this PHP code before, and it seems to work fine in everything else I've done. Any insights?
Thank you.
Related
I'm trying to send the form data to a php script using axios.
Is the syntax of axios correct?
How can I view the data sent via the post method?
I just started programming in vuetify and php, so I need a little help
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
this.axios.post('http://localhost/index.php/',{
name : this.name, user : this.username
})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
},
}
in the php file there's :
<?php
require_once 'limonade.php';
$data = $_POST;
dispatch('/api/', 'test1');
function test1()
{
return 'Hello';
}
run();
Your php only acts when it's a GET Call, limonade's dispatch() is for GET only.
In your php you are creating a GET endpoint on the /api/ url that will execute the test1 function. Meaning when you call /api via get, you will get Hello as answer.
if you want that to be POST (without touching your javascript) the php should be something like:
# '/' because you are calling to http://localhost/index.php/ it could be '/whatever' if you call http://localhost/whatever (assuming you have configured everythign as limonade recomends)
function test2()
dispatch_post('/', 'test2');
{
return 'Hello via post';
}
I'm trying to create an app in AngularJS that aggregates data from multiple APIs. With some public APIs there are request limits and much of the data I want to pull is not updated very frequently, so only one request a month for a particular ID is necessary. To get past this, I've set up a Factory that first checks for a local file on the server, if it is not present, it then goes to the API and performs a GET request.
From there, once the request is complete, I want to save that file to the server with a name set by a field in the response.
I've found some examples using PHP with AngularJS but I'm not sure on how to save the JSON file with the dynamic name...or if this is even the best thing to do in order to avoid the request limits.
var apiUrl = 'https://example.com/api?userID=';
$http.get(apiUrl + $stateParams.userID).
success(function(data) {
$scope.content = data;
$scope.userID = data.userID
function(){
$http.post('saveJson.php', $scope.content).then(function() {
// log success
});
};
}).
error(function() {
// log error
});
PHP
<?php
$json = file_get_contents("php://input");
$file = fopen('/var/www/USERID.json','w+');
fwrite($file, $json);
fclose($file);
?>
If you do this in a service, and just call a method from a view button click, it would be more like this:
angular.module('app.services', [
])
.service('MyService', function ($http) {
var MyService = this;
this.aggregatedData = { content: [], filename: null };
this.apiUrl = 'https://example.com/api?userID=';
this.saveUrl = 'saveJson.php';
this.getData = function (url) {
return $http.get(url + $stateParams.userID).then(function (response) {
MyService.aggregatedData.content.push(response.data);
});
};
this.saveData = function (url, fileName) {
this.aggregatedData.filename = fileName;
return $http.post('saveJson.php', this.aggregatedData).then(function () {
// do something with the post response if desired
});
};
})
Then wire up buttons in your view to fetch and save by having the controller call the service methods.
This is on Internet Explorer only.
I have a factory that provides notifications for my app.
The input for those notifications is a file (qc.sta) that is created automatically by a third party software and is dropped in a specific folder.
Whenever that file exists, a new notification is added to the app.
My mechanism would be to get the data from that qc.sta file and then delete it after collecting the data.
To delete a file I need to execute a PHP that deletes the file, but this seems to have to be done inside a $http.get, so I end up with an $http.get inside another $http.get.
What happens is that the notifications (triggered on a $interval inside the controller) keep popping up continuously, despite the file being deleted.
My factory is as below:
myApp.factory("qcSTA", function ($http, $q) {
return {
apiPath: "data/qc.sta?rnd=" + new Date().getTime(), //randomizing request to prevent caching
getNotifications: function () {
//Creating a deferred object
var deferred = $q.defer();
//Calling Web API to fetch notifications
$http.get(this.apiPath, { headers: { 'Cache-Control': 'no-cache'} })
.success(function (response) {
//Passing data to deferred's resolve function on successful completion
//Does whatever needs to be done to the response before passing it on
function deleteFile() {
$http.get("deleteFile.php");
return false
};
deleteFile();
deferred.resolve(JSON.parse('{"item" : "' + response.itemNumber + '", "description" : "' + response.desc + '"}'));
})
.error(function () {
//Sending a friendly error message in case of failure
deferred.reject("An error occured while fetching items");
});
//Returning the promise object
return deferred.promise;
}
}
});
And my controller:
myApp.controller("notificationController", function ($scope, $location, $interval, $q, qcSTA) {
function getNotifications() {
qcSTA.getNotifications()
.then(function (data) {
$scope.notifications.push(data);
},
function (errorMessage) {
$scope.error = errorMessage
});
}
}
How can I ensure the notification only pops up once rather than going in circles?
Could this be cache related?
If I refresh the browser, it won't get more notifications, it's like it finally detects the qc.sta file isn't there anymore.
I am battling with this code run on crome then it has been throw the following error.but everything is working fine in firefox
1)Uncaught SyntaxError: Unexpected token }
2)Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=lens_admin&p1=Erro…gleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.28%2Fangular.min.js%3A18%3A170)
inside my Controller:
angular.module('lens_admin.controllers', ['angularFileUpload']).
.controller('adminController', function($scope,$http,$location,$upload) {
$scope.brand_edit_submit = function(bid) {
var brand_type_editObj=new Object();
brand_type_editObj.edit_mode='brand';
brand_type_editObj.bid=bid;
brand_type_editObj.brand_type_edit=$scope.brand_type_edit;
$http.post("ajax/frame_list_update.php",{brand_type_editObj}). //first error focus here.am i correct to passing Object to server side..
success(function(data, status, headers, config) {
alert(data);
$scope.brand_type_tables();
$scope.lens_brand_table();
$('.modal').modal('hide');
}).
error(function(data, status, headers, config) {
alert("Please Try Again..!");
});
}
});
i have embedded files for "angularFileUpload" module that included in my "admin.controllers".what is wrong with my code.this issue occured only in crome..any one can give me some ideas..
Thanks Advance..
This is the error line:
$http.post("ajax/frame_list_update.php",{brand_type_editObj})
This is because
{brand_type_editObj}
Isn't a proper object.
It needs to be
{ someName: brand_type_editObj }
Where I have introduced a key someName. JavaScript objects are key/value pairs. So there always needs to be a Key and there always needs to be a Value.
2)Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=lens_admin&p1=Erro…gleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.28%2Fangular.min.js%3A18%3A170)
This occured because it probably couldn't find ['angularFileUpload']. But with out seeing the main script its hard to know for sure
Here is the correct code
Few errors like double "." b/w module and controller
second:- Key is not assigned to object in $http call.
angular.module('lens_admin.controllers', ['angularFileUpload'])
.controller('adminController', function($scope, $http, $location, $upload) {
$scope.brand_edit_submit = function(bid) {
var brand_type_editObj = new Object();
brand_type_editObj.edit_mode = 'brand';
brand_type_editObj.bid = bid;
brand_type_editObj.brand_type_edit = $scope.brand_type_edit;
$http.post("ajax/frame_list_update.php",{"data":brand_type_editObj}).
success(function(data, status, headers, config) {
alert(data);
$scope.brand_type_tables();
$scope.lens_brand_table();
$('.modal').modal('hide');
}).
error(function(data, status, headers, config) {
alert("Please Try Again..!");
});
}
});
In my footer.php I have this code which i needed for my api references
<script type="text/javascript">
/** Override ajaxSend so we can add the api key for every call **/
$(document).ajaxSend(function(e, xhr, options)
{
xhr.setRequestHeader("<?php echo $this->config->item('rest_key_name');?>", "<?php echo $this->session->userdata('api_key')?>");
});
</script>
It works fine in my project without any error but when I started working on file upload and I'm using ajaxfileupload to upload file, I got this error whenever i upload the file.
TypeError: xhr.setRequestHeader is not a function
xhr.setRequestHeader("KEY", "123456POIUMSSD");
Here is my ajaxfileuplod program code:
<script type="text/javascript">
$(document).ready(function() {
var DocsMasterView = Backbone.View.extend({
el: $("#documents-info"),
initialize: function () {
},
events: {
'submit' : 'test'
},
test: function (e) {
e.preventDefault();
var request = $.ajaxFileUpload({
url :'./crew-upload-file',
secureuri :false,
fileElementId :'userfile',
dataType : 'json',
data : {
'title' : $('#title').val()
},
success : function (data, status)
{
if(data.status != 'error')
{
$('#files').html('<p>Reloading files...</p>');
refresh_files();
$('#title').val('');
}
alert(data.msg);
}
});
request.abort();
return false;
}
});
var x = new DocsMasterView();
});
</script>
Can anyone here fix my problem. Any suggestion/advice in order to solve my problem.
As I understand from your comments, setRequestHeaders works fine with regular ajax calls. At the same time it is not available when ajaxFileUpload is used. Most likely that is because transport method does not allow to set headers (for instance, in case when iframe is used to emulate upload of files in ajax style) . So, possible solution is to place a key into your form data:
$(document).ajaxSend(function(e, xhr, options)
{
if(xhr.setRequestHeader) {
xhr.setRequestHeader("<?php echo $this->config->item('rest_key_name');?>", "<?php echo $this->session->userdata('api_key')?>");
else
options.data["<?php echo $this->config->item('rest_key_name');?>"] = "<?php echo $this->session->userdata('api_key')?>";
});
Note: I'm not sure if options.data is a correct statement, just do not remember structure of options object. If proposed code does not work - try to do console.log(options) and how
to get an object with data that should be posted (it might be something like options.formData, I just do not remember exactly)
And on server side you will just need to check for key in headers or form data.