Problems populating a select list with angular js and php - php

I am trying to populate a select list with data from my db (php & mysql). I am working with AngularJs and Angular Material. So for i am not able to show the data from the db in the list
db situation:
tblProjectType -> name of table
2 rows:
id_ProjectType
project_type
Any help or pointers would be great.
This is my html code:
<form ng-controller="AppCtrl">
<div layout="row">
<md-select-label>Project type</md-select-label>
<md-select ng-model="project_type" name="project_type" placeholder="Choose a project type" id="containerProjectType">
<md-option ng-repeat="projecttype in projecttypes" value="{{projecttype.id_ProjectType}}">{{projecttype.project_type}}</md-option>
</md-select>
</div>
</form>
The code of my app.js is:
var app = angular.module("DragDrop", ['ngMaterial']);
app.controller('AppCtrl', function($scope, $mdDialog, $http) {
$scope.projectTypeInfo = [];
var getProjectTypeFunction = function(succesFn, errorFn)
{
$http.get('db.php?action=get_ProjectType_info')// call to the server
.succesFn(function(data){
succesFn(data); //call the function passed into getProjectTypeFunction with the data from the server
console.log('Retrieved data from server');
})
.error(errorFn || function() {
console.log("Error in retrieving data from server");
})
}
this.reloadProjectTypeList = function()
{
getProjectTypeFunction(
/* success function */
function(data) {
//debugger;
$scope.projectTypeInfo = data;
//digest recycle
//if (!$scope.$$phase) { $scope.$apply(); }
},
/* error function */
function()
{
alert("Server load failed");
})
};
My php code is:
<?php
include('config.php');
//echo ('test' . $_GET['action']);
switch($_GET['action']) {
case 'get_ProjectType_info' :
get_ProjectType_info();
break;
}
/** Function to data from tblProjectType **/
function get_ProjectType_info(){
$qry = mysql_query('SELECT * from tblProjectType');
echo("test");
//echo(qry);
$data = array();
while($rows = mysql_fetch_array($qry))
{
$data[] = array(
"id_ProjectType" => $rows['id_ProjectType'],
"project_type" => $rows['project_type']
);
}
print_r(json_encode($data));
return json_encode($data);
}
?>

So for starters lets clean up your JS. We can reduce what you have to this:
var app = angular.module("DragDrop", ['ngMaterial']);
app.controller('AppCtrl', function($scope, $mdDialog, $http)
{
$scope.projectTypeInfo = [];
$scope.getProjectTypeFunction = function()
{
$http.get('db.php?action=get_ProjectType_info')
.success(function(data, status, headers, config)
{
$scope.projectTypeInfo = data;
console.log('Retrieved data from server');
console.log(data);
})
.error(function(data, status, headers, config)
{
console.log("Error in retrieving data from server");
console.log(data,status);
});
};
$scope.getProjectTypeFunction(); //-- call the function that invokes $http.get()
};
In PHP your function needs to echo the data via echo json_encode($data);, not return it (as stated by #Avalanche).
Now, your console should output something, but you need to remove console.log("test"); from your PHP as that will surely cause an error.
edit
Currently your repeat states:
<md-option ng-repeat="projecttype in projecttypes" value="{{projecttype.id_ProjectType}}">{{projecttype.project_type}}</md-option>
We have stored your data in $scope.projectTypeInfo therefore it needs to be modified to:
<md-option ng-repeat="projecttype in projectTypeInfo" ng-value="projecttype.id_ProjectType">{{projecttype.project_type}}</md-option>

Related

Why doesn't ng-repeat update dynamically?

I've literally checked out every single ng-repeat question out there but a lot of them don't deal with databases and people just use arrays in JS and a simple $scope.array.push("stuff") works for them.
I've tried $scope.apply, $rootScope and even calling the GET request right after a successful POST request.
I have a form with 2 text inputs, date and content.
When the submit button is pressed, date and content are added into a MySQL database using PHP.
The data is added just fine to the MySQL database and retrieving also works properly.
Even the GET request inside the successful POST request is executed.
So I don't understand why it forces me to refresh the page to see the updated ng-repeat results.
Am I missing something?
Any help or suggestions is greatly appreciated, thanks!
Relevant HTML code
<div ng-controller="insertController">
<h2> What I learned today </h2>
<form>
Date <br>
<input type="text" ng-model="date"><br><br>
Content <br>
<textarea rows="10" cols="50" ng-model="content"></textarea><br><br>
<input type="button" value="Submit" ng-click="insertdata()">
</form>
</div>
<div ng-controller="fetchController">
<span ng-repeat="item in results">
{{item.date}}<br>
{{item.content}}<br><br>
</span>
</div>
insertController.js
var app = angular.module('myApp', []);
app.controller('insertController', function($scope, $http) {
$scope.insertdata = function() {
$http({
method: 'POST',
url: 'http://localhost/storestuff/insert.php',
data: {'date':$scope.date, 'content':$scope.content, 'in':'json-format'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(res) {
console.log("Successful response", res)
$scope.date = "";
$scope.content = "";
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
alert("GOT NEW DATA");
$scope.results = response.data; // Allow angular to access the PHP output data
});
$scope.apply;
})
.catch(function(err) {
console.error("Error with POST", err);
});
}
});
insert.php
<?php
header('Access-Control-Allow-Origin: *');
$theConnection = mysqli_connect("localhost", "root", "", "storestuff");
if(mysqli_connect_errno()) {
echo "Failed to connect to MySQL.";
}
$theData = json_decode(file_get_contents('php://input'));
$date = mysqli_real_escape_string($theConnection, $theData->date);
$content = mysqli_real_escape_string($theConnection, $theData->content);
mysqli_query($theConnection, "INSERT INTO thestuff(date, content) VALUES('$date', '$content')");
mysqli_close($theConnection);
?>
fetchController.js
app.controller('fetchController', function ($scope, $http) {
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
$scope.results = response.data; // Allow angular to access the PHP output data
});
});
fetch.php
<?php
header('Access-Control-Allow-Origin: *'); // clientside(Node) <-> serverside(PHP)
$mysqli = new mysqli("localhost", "root", "", "storestuff");
if($mysqli->connect_error) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$query = "SELECT * FROM thestuff";
$theData = array();
if($result = $mysqli->query($query)) {
while($row = mysqli_fetch_array($result)) {
$theData[] = array(
'date'=>$row['date'],
'content'=>$row['content']);
}
echo json_encode($theData); // Echo the output for the controller to access
$result->free(); // Free the result set
}
else {
echo "0 results.";
}
$mysqli->close(); // Close the connection
?>
The problem with this code is that you have two different controllers, both with separate scopes. Inserting/updating the $scope.results object/array in one controller, will not update the other $scope; they are separate distinct scopes, both with a copy of the data.
Using two controllers looks correct in your use case. However you should be using a service to access your remote data. Check out this answer for some advice on this https://stackoverflow.com/a/20181543/2603735.
Using a service like in that answer, will allow you to store the array/object of remote data in one place, and reference the SAME object from both controllers. Therefore updating from one controller, will also update the other.
For anyone who will ever stumble on my question, I don't want to just leave my broken code there with no answer but neither can I edit the question and put in my answer cause that would defy the purpose of StackOverflow.
So here is my answer to my own question.
I had to make quite a few changes to what I had before. The biggest change by far, is how I handled the data that was returned by fetch.php.
Instead of just taking the output into $scope.results = response.data;, which would work fine if I wasn't dynamically adding to the database, but for this case, I ended up using a service. (Thanks #jayden-meyer for suggesting Angular services.)
The service allowed me to access the same array from my insertController and from my fetchController instead of having a copy of the same array in both controllers which was my problem.
No changes in the HTML code.
No changes to insert.php.
No changes to fetch.php.
insertController.js
I removed the extraneous GET request I had inside the .then method which was completely unneeded since I can just push to the existing array.
(Thanks #charlietfl for the tip)
Instead I added resultsService.addItem($scope.date, $scope.content); inside of the .then method.
I also added my service as an argument.
app.controller('insertController', function($scope, $http, resultsService) {
result.js
app.service('resultsService', function() {
var results = new Array();
var addItem = function(date, content) {
var obj = new Object();
obj["date"] = date;
obj["content"] = content;
results.push(obj);
}
var getItems = function() {
return results;
}
return {
addItem: addItem,
getItems: getItems
};
});
fetchController.js
var size = 0;
var count = 0;
app.controller('fetchController', function ($scope, $http, resultsService) {
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
size = (response.data).length;
while(count < size) {
var date = response.data[count].date;
var content = response.data[count].content;
resultsService.addItem(date, content);
count++;
}
size = 0;
count = 0;
$scope.results = resultsService.getItems();
});
});

Infinite Scrolling of dynamic data with ionic 1 and angular js 1

How can I do infinite scrolling in ionic 1 and angular js 1 with dynamic data (Http request)from database ?
HTML :
<ion-view view-title="Playlists">
<ion-content>
<ion-list>
<ion-item class="item-avatar" ng-repeat="item in items">
<h2>{{item.name}} -{{item.id}}</h2>
<p>{{item.iso_code_2}} {{item.iso_code_3}}</p>
</ion-item>
</ion-list>
<div ng-if="hasData">
<ion-infinite-scroll on-infinite="loadMore()" distance="5%">
</ion-infinite-scroll>
</div>
</ion-content>
</ion-view>
Controller.js
This is my angularjs controller. Use a factory named 'CountryService' which is doing http call to get server data. In formdata = {limit:serviceconfig.showlimit,page:page}; I sent limit =10 where I set in config.js service,and set page =1 for the first time.
For the first time GetDefault is called after scrolling GetLoadMore will be called with page =2 and limit=10 with next 10 new data.
angular.module('starter.usercontroller', [])
.controller('UserCtrl', function($scope, CountryService, $ionicModal,
$timeout, $http, serviceconfig, $ionicPopup,$state, ionicDatePicker, $filter) {
$scope.hasData=1; // If data found
$scope.items = [];
CountryService.GetDefault().then(function(items){
$scope.items = items;
});
$scope.loadMore = function() {
CountryService.GetLoadMore().then(function(items){
$scope.items = $scope.items.concat(items);
if(items.length>0)
{
$scope.$broadcast('scroll.infiniteScrollComplete'); // If has data then load more
}
else
{
$scope.hasData=0; // If no more data to load
}
});
};
})
.factory('CountryService',
['$http','serviceconfig',function($http,serviceconfig){
var items = [];
var page =1;
var formdata = {limit:serviceconfig.showlimit,page:page};
return {
GetDefault: function(){
formdata = {limit:serviceconfig.showlimit,page:page};
return $http.post(serviceconfig.serviceUrl+ "all-countries",formdata).then(function(response){
if(response.data.status==1)
{
items = response.data.countries;
}
else
{
items =[];
}
return items;
});
},
GetLoadMore: function(){
formdata = {limit:serviceconfig.showlimit,page:page};
return $http.post(serviceconfig.serviceUrl+ "all-countries",formdata).then(function(response){
page = page+1;
if(response.data.status==1)
{
items = response.data.countries;
}
else
{
items =[];
}
return items;
});
}
}
}]);
Config.js For configuration
In this config.js I set the server url and limit, how many data I want to fetch from server each scroll. 'configService' service I inject in my js controller.
angular.module('starter.configService', [])
.service('serviceconfig',function(){
this.serviceUrl='http://192.168.1.116/ionicserver/service/';
this.showlimit=10;
})
PHP SERVER SITE CODE:
I am using php laravel 5.1. So this is my php controller function for getting county list by below function
public function postAllCountries() // Countries
{
$data = Request::all();
$limit= $data['limit'];
$page = $data['page'];
$offset = ($page - 1) * $limit;
$countries = Country::where('id','>',0)->take($limit)->skip($offset);
$countries = $countries->get()->toArray();
if(!empty($countries))
{
echo json_encode(array('status'=>1,'msg'=>'Successfully Registered','countries'=>$countries));
}
else
{
echo json_encode(array('status'=>0,'msg'=>'No data found'));
}
exit;
}

Why my ajax function does not work on yii2

Hello *** please How can i use ajax function in yii2
in fact I am working on a product of this framework(yii2), not on it directly, But I think it's the same principle. and i want to draw charts (chartJs or googleChart or d3 ... anyway)
so in index file of backend area (xx/xx/xx/dashboard/index.php) I want to send an ajax request to an another php file (simple and logical)
this one is placed in the same folder as index (xx/xx/xx/dashboard) , but nothing happens ! :(
I notice that if I test my two files (indexAjax and phpDB) outside framework folders I get a nice result
but once it's has within framework files, they will no longer work :(
my code is as follows :
1/ part of my index file
<canvas id="mycanvas" width="400" height="400"></canvas>
<script>
$(function()
{
$.ajax({
url: "chartData.php",
type:'POST',
data:{'trigger':'trigger'},
success: function(data) {
alert(data);
console.log(data);
var idTab = [];
var resultatTab = [];
for(var i in data) {
idTab.push("data " + data[i].id);
resultatTab.push(data[i].resultat);
}
var chartdata = {
labels: idTab,
datasets : [
{
label: 'Player Score',
backgroundColor: 'deepskyblue',
borderColor: 'dodgerblue',
hoverBackgroundColor: 'orange',
hoverBorderColor: 'yellow',
data: resultatTab
}
]
};
var ctx = $("#mycanvas");
var doughnutGraph = new Chart(ctx, {
type: 'doughnut',
data: chartdata,
options:{responsive:false}
});
},
error: function(data) {
alert(JSON.stringify(data));
console.log(data);
}
});
}); // fin jQuery
</script>
2/ the 2nd file (php)
<?php
if (isset($_POST['trigger']))
{
//setting header to json
header('Content-Type: application/json');
//database
define('DB_HOST', '127.0.0.1');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_NAME', 'lab');
//get connection
$mysqli = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
if(!$mysqli){
die("Connection failed: " . $mysqli->error);
}
//query to get data from the table
$query = sprintf("SELECT * FROM score");
//execute query
$result = $mysqli->query($query);
//loop through the returned data
$data = array();
foreach ($result as $row) {
$data[] = $row;
}
//free memory associated with result
$result->close();
//close connection
$mysqli->close();
//now print the data
print json_encode($data);
}
NB: I must also say that I did not respect the principle of the MVC
i put everything in a same folder ... but I think it's still a choice
thanks a lot
I think you have to look how the routing in yii2 works
http://www.yiiframework.com/doc-2.0/guide-structure-overview.html
or here
http://www.yiiframework.com/doc-2.0/guide-start-hello.html
you can not directly call an php file ..
for example, in javascript:
$.get('/site/user-messages', function (data, status) {
if (status !== 'success') {
console.log('ERROR: '+ status);
return;
}
allData = JSON.parse(data);
});
here site is the controller and user-messages is the action
in this case the prettyUrl mode is enabled in urlManager
Add the content of you charData.php files in a proper action eg: inside siteController.php
public function actionChartData() {
your code
.........
return $this->render('your_related_view', [
/* your vars */
'my_var' => $my_var,
]);
}
the call the action i ajax using
$.ajax({
url: <?php echo \yii\helpers\Url::to(['/site/chart-data']) ?>,
type:'POST',
data:{'trigger':'trigger'},
success: function(data) {
........

JQuery AJAX PHP post method issue

I am trying to post values form HTML file through AJAX as a request and get a JSON formatted string as a response from PHP.
I have done the following
The Javascript file:
$(document).ready(pageLoad);
function pageLoad()
{
$("#submit").click(submitClick)
}
function submitClick()
{
var data = {Year:"2005"};
$.getJSON("db/connect.php", data, fetchData);
}
function fetchData(data)
{
$.each(data, function(index, element) {
$("#content").append(data[index].Name + "<br />");
})
}
The PHP file
<?php
$server = "localhost";
$user = "amey";
$pass = "";
$database = "education";
echo $_POST["Year"];
$conn = mysql_connect($server, $user, $pass) or die("Unable to connect to MySQL");
mysql_select_db($database, $conn);
$query = "select * from BabyNames";
$result = mysql_query($query) or die(error_get_last());
$json = array();
while($row = mysql_fetch_array($result))
{
$json[] = $row;
}
echo json_encode($json);
mysql_close($conn);
?>
I can not retrieve the Year value in the PHP file. I've also tried using $.post and $.ajax function. In $.ajax function, when I remove the dataType: "json", the post method works.
Please make changes in your code,
if your php code working fine.
$(document).ready(function() {
var pageLoad = function() {
$("#submit").click(function(){
submitClick();
})
});
pageLoad();
});
if you want submit form/data on click "#submit" then no need to pageLoad function
$(document).ready(function() {
$("#submit").click(function(){
submitClick();
});
});
});
$.getJSON() method does an HTTP GET and not POST. You need to use $.post().
$.post(url, dataToBeSent, function(data, textStatus) {
//data contains the JSON object
//textStatus contains the status: success, error, etc
}, "json");
click here for solution more solution

Why is this jquery ajax call not returning data from my php script?

I'm new to jQuery, and have not been able to debug this ajax call in Firebug:
This is my ajax call:
var styndx = $('#studylist option:selected').val();
var studyname = $('#edit_field').val();
$.post("saveStudyName.php", {'type': 'update', 'studyname':studyname, 'styndx':styndx},
function(resultmsg) {
$('#edit_field').val('');
$('#savebtn').attr('disabled',true);
refresh_studynames();
});
And this is the function refresh_studynames:
function refresh_studynames()
{
$.ajax({
url: 'getStudyNames.php',
data: "",
dataType: 'json',
error: function() {
alert('Refresh of study names failed.');
},
success: function(data)
{
$data.each(data, function(val, sname) {
$('#studylist').append( $('<option></option>').val(val).html(sname) )
});
}
});
}
Finally, this is the php script getStudyNames.php ($dbname,$dbconnect, $hostname are all populated, and $dbconnect works; the backend database is Postgres, and pg_fetch_all is a Postgres function in PHP that returns result as an array):
$dbconnect = pg_pconnect("host=".$hostname." user=".$dbuser." dbname=".$dbname);
if (!$dbconnect) {
showerror(0,"Failed to connect to database",'saveStudyName',30,"username=".$dbuser.", dbname=".$dbname);
exit;
}
$sql = "SELECT ST.studyindex,ST.studyabrv AS studyname
FROM ibg_studies ST
ORDER BY studyname";
$fetchresult = pg_exec($dbconnect, $sql);
if ($fetchresult) {
$array = pg_fetch_all($fetchresult);
echo json_encode($array);
} else {
$msg = "Failure! SQL="+$sql;
echo $msg;
}
Any help much appreciated....
The line
$('#studylist').append( $('<option></option>').val(val).html(sname) );
looks wrong.
I'm not too sure but you could try :
var $studylist = $('#studylist').empty();
$data.each(data, function(i, record) {
$studylist.append( $('<option/>').html(record.sname) );
});

Categories