GET JSONP data from php file in Angular Controller - javascript

Recently, I began to study Angular. So much I do not know. I'm trying to get json data from a php file to use within an Angular controller. But the data from php file does not exceed.
controllers.js:
app.controller('MainCtrl',['$scope', '$resource', '$http',
function($scope, $resource,$http) {
$http.get('/xbmc.php').success(function(data) {
$scope.data = data;
});
}]);
xbmc.php:
<?
include('sys/inc/config.inc.php');
include(SMARTY_DIR.'Smarty.class.php');
include(BASE_DIR .'sys/inc/classes.inc.php');
include(BASE_DIR .'sys/inc/init.inc.php');
include(BASE_DIR .'xbmcApi.php');
$jsonData = new xbmcApi($_GET['action']);
/**
if (MEGAKINO_LOGED)
{
**/
$json = $jsonData->getResult();
/**
}
else
$json = array('authStatus' => '0');
**/
echo json_encode($json);
?>
index.html:
<body ng-controller="MainCtrl">
<div class="wrapper">
<h2>{{title}}</h2>
<div class="row">
<div class="col-md-1 col-sm-2 col-xs-4" style="margin-top: 0.5%;" ng-repeat="item in data.items">
<div class="image" style="margin-bottom: 1%">
<a data-ng-href="#!/seasons/serie/{{item.id}}">
<img data-ng-src="/files/series/thumb-{{item.id}}.jpg" alt=""/>
</a>
</div>
<div class="info">
<a data-ng-href="#!/seasons/serie/{{item.id}}">
<b>{{item}}</b>
<u>Рейтинг: {{item.rate}}</u>
</a>
</div>
</div>
</div>
</div>
</body>

Your php code tells that your json will be build if a $_GET['action'] param is passed:
$jsonData = new xbmcApi($_GET['action']);
Yet, you are not passing any data as a query string from your angular controller. Try something like:
app.controller('MainCtrl',['$scope', '$resource', '$http',
function($scope, $resource,$http) {
$http({
url: '/xbmc.php',
method: "GET",
params: {action: 'some_action'}
}).success(function(data) {
$scope.data = data;
});
}]);

AS #CharlieH said, check for errors on your console:
app.controller('MainCtrl',['$scope', '$resource', '$http',
function($scope, $resource,$http) {
$http.get('/xbmc.php')
.then(function(response) {
$scope.data = response.data;
})
.catch (function(error) {
//check for errors here
console.log(error);
throw error;
});
}]);
Also the .success method has been deprecated. We should all be migrating to using .then and .catch. For more information on that see: Deprecation of the .success and .error methods in the $http service

Related

Expected Array but received ...(JSON)... AngularJS Error

I'm learning Angular1 from Adam Freeman's ,,Pro AngularJS" book. I've got a problem with building a DeployD app he's describing in chapters 6-8 - it seems like my code doesn't want to read JSON
That's my HTML:
<!DOCTYPE html>
<html ng-app="sportsStore" lang="pl">
<head>
<title>SportsStore</title>
<script src="components/angular.js"></script>
<script src="components/angular-resource.js"></script>
<link href="components/bootstrap.css" rel="stylesheet" />
<link href="components/bootstrap-theme.css" rel="stylesheet" />
<script>
angular.module("sportsStore", ["customFilters"]);
</script>
<script src="controllers/sportsStore.js"></script>
<script src="filters/customFilters.js"></script>
<script src="controllers/productListControllers.js"></script>
</head>
<body ng-controller="sportsStoreCtrl">
<div class="navbar navbar-inverse">
<a class="navbar-brand" href="#">SKLEP SPORTOWY</a>
</div>
<div class="panel panel-default row" ng-controller="productListCtrl">
<div class="alert alert-danger" ng-show="data.error">
Błąd ({{data.error.status}}). Dane produktu nie zostały wczytane.
Kliknij tutaj, aby spróbować ponownie
</div>
<div class="panel panel-default row" ng-controller="productListCtrl"
ng-hide="data.error">
<div class="col-xs-3">
<a ng-click="selectCategory()"
class="btn btn-block btn-default btn-lg">Strona główna</a>
<a ng-repeat="item in data.products | orderBy:'category' |
unique:'category'" ng-click="selectCategory(item)" class=" btn btn-block
btn-default btn-lg" ng-class="getCategoryClass(item)">
{{item}}
</a>
</div>
<div class="col-xs-8">
<div class="well"
ng-repeat="item in data.products | filter:categoryFilterFn |
range:selectedPage:pageSize">
<h3>
<strong>{{item.name}}</strong>
<span class="pull-right label label-primary">
{{item.price | currency}}
</span>
</h3>
<span class="lead">{{item.description}}</span>
</div>
<div class="pull-right btn-group">
<a ng-repeat="page in data.products | filter:categoryFilterFn |
pageCount:pageSize" ng-click="selectPage($index + 1)" class="btn
btn-default" ng-class="getPageClass($index + 1)">
{{$index + 1}}
</a>
</div>
</div>
</div>
</body>
</html>
and the sportStore.js controller
angular.module("sportsStore")
.constant("dataUrl", "http://localhost:5500/products")
.controller("sportsStoreCtrl", function ($scope, $http, dataUrl) {
$scope.data = {};
$http.get(dataUrl)
.then(function (data) {
$scope.data.products = data;
},
function (error) {
$scope.data.error = error;
});
});
I'm using DeployD to build an API, and the problem is that when I try to run my app, the error shows up in console:
Error: [filter:notarray] Expected array but received:
{"data":[{"name":"Kajak","description":"Łódka przeznaczona dla jednej
osoby","category":"Sporty
Wodne","price":275,"id":"d9b9e4fcb9df3853"},{"name":"Kamizelka
ratunkowa","description":"Chroni i dodaje uroku","category":"Sporty
wodne","price":49.75,"id":"3c1cceedb44ddb84"},{"name":"Piłka","description":"Zatwierdzona
przez FIFA rozmiar i waga","category":"Piłka
Nożna","price":19.5,"id":"447a2079a8488932"},{"name":"Flagi
narożne","description":"Nadadzą Twojemu boisku profesjonalny
wygląd","category":"Piłka
Nożna","price":34.95,"id":"2b2dd597f18bb8a7"},{"name":"Stadion","description":"Składany
stadion na 35000 osób","category":"Piłka
Nożna","price":79500,"id":"2cfe0f6767240bf9"},{"name":"Czapka","description":"Zwiększa
efektywność mózgu o
75%","category":"Szachy","price":16,"id":"dfc137db43574b4a"},{"name":"Niestabilne
krzesło","description":"Zmniejsza szansę
przeciwnika","category":"Szachy","price":29,"id":"e2b644c5091d28ca"},{"name":"Ludzka
szachownica","description":"Przyjemna gra dla całej
rodziny","category":"Szachy","price":75,"id":"f945806bb011895d"},{"name":"Błyszczący
król","description":"Pokryty złotem i wysadzany diamentami
król","category":"Szachy","price":1200,"id":"fab242704bb38b64"}],"status":200,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:5500/products","headers":{"Accept":"application/json,
text/plain, /"}},"statusText":"OK"}
http://errors.angularjs.org/1.6.0-rc.1/filter/notarray?p0=%7B%22data%22%3A%…son%2C%20text%2Fplain%2C%20*%2F*%22%7D%7D%2C%22statusText%22%3A%22OK%22%7D
at angular.js:68
at angular.js:20392
at fn (eval at compile (angular.js:15095), :4:388)
at regularInterceptedExpression (angular.js:16203)
at Scope.$digest (angular.js:17732)
at Scope.$apply (angular.js:18006)
at done (angular.js:12150)
at completeRequest (angular.js:12376)
at XMLHttpRequest.requestLoaded (angular.js:12304)
I tried to skim through similar errors on SO but none of the solutions seemed to work for me. Did someone have a similar problem?
ng repeat works with an arrays but as per the response getting from the API in then() method is not the data itself but it is having a property named as data which is the actual array that you have to pass in ng-repeat.
So, instead of using $scope.data.products = data use $scope.data.products = data.data
----------OR----------
.then(function (response) {
$scope.data.products = response.data;
}
The error message shows the filter refusing to process the response object instead of the data array. Expected array but received: {data:[..., headers: ...
The .then method of the $http service returns a response object, not data.
angular.module("sportsStore")
.constant("dataUrl", "http://localhost:5500/products")
.controller("sportsStoreCtrl", function ($scope, $http, dataUrl) {
$scope.data = {};
$http.get(dataUrl)
//.then(function (data) {
// $scope.data.products = data;
.then(function (response) {
$scope.data.products = response.data;
},
function (error) {
$scope.data.error = error;
});
});
Data is only one property of the response object:
$http(...).
then(function onSuccess(response) {
// Handle success
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
}, function onError(response) {
// Handle error
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
...
});
ng repeat and filter works with array, you need to access the data
angular.module("sportsStore")
.constant("dataUrl", "http://localhost:5500/products")
.controller("sportsStoreCtrl", function ($scope, $http, dataUrl) {
$scope.data = {};
$http.get(dataUrl)
.then(function (data) {
$scope.data.products = data.data;
},
function (error) {
$scope.data.error = error;
});
});
Angular expects the data variable to be type of array.
$scope.data = [];
Then try following code:
$http.get('dataUrl')
.success(function(data) {
$scope.data = data;
}).error(function(data, status) {
$log.error('Error ' + status + ' unable to get data from server.');
});
Also remember to add to your controller the $log to properly display bugs in console:
.controller('sportsStoreCtrl', ['$scope', '$http', '$log', function ($scope, $http, $log)

How do I get my request data into my $scope

I m currently really stuck on this topic.
I want to append the response data that I am retrieving from Express to my angular $scope and then redirect the user to their profile page.
My Controller Function looks like this:
$scope.login = function($event){
$event.stopPropagation();
$http({
method: 'POST',
url: '/login',
data: {
email: $scope.email,
password: $scope.password
}
}).success(function(data){
console.log(data.events)
$scope.events = data.events
$location.path('/profile');
}).error(function(err){
console.log(err)
})
Once I try to log in I get the logged data and then I'm redirected as desired. But my ng-repeat directive doesn't update.
JSON Output from my logged data:
[{
"type":"fussball",
"distance":"1",
"date":"Morgen",
"time":"10:30",
"maxAttendees":10,
"attendees:[
1345455466,
323232324,
454554534343,
898493839489,
892839283928,
283293283983]}
ng-repeat section:
<div ng-class="{'first': $first}" class="event-item"ng-repeat="event in events">
<div class="event-type {{event.type}}"></div>
<div class="event-seperator"></div>
<div class="event-body">
<div class="event-body-inner">
<span class="date"></span>
<p class="main">{{event.date}}</p>
<p class="sub">{{event.time}}</p>
</div>
<div class="event-body-inner">
<span class="attendees"></span>
<p class="main">{{event.attendees.length}}{{checkAttendees($index)}}</p>
<p class="sub">TEILNEHMER</p>
</div>
<div class="event-body-inner">
<span class="distance"></span>
<p class="main">{{event.distance}}</p>
<p class="sub">KM</p>
</div>
</div>
<div class="event-seperator"></div>
<div ng-click="selecEvent($event)" class="eventGo hvr-bounce-to-left">
<p>GO</p>
</div>
<div class="event-clicked">
<p>+ ZU DEINEN EVENTS HINZUGEFÜGT</p>
</div>
I'm actually not so familiar with asynch/synch programming so I hope someone can give me a hint ;) .
Thanks in advance!
You need to tell angular that there is an async update on the event list
}).success(function(data){
console.log(data.events)
$scope.events = data.events
$scope.$apply(); // <----- try to add this line
$location.path('/profile');
Maybe you would like to read:
When to use $scope.$apply()
and to watch:
Difference between $apply and $digest
The best way is to use a factory for this. I was about to write it but I found another question in another post.
Please up-vote the original poster if you like the comment.
https://stackoverflow.com/a/21855302/1549291
EDIT: Added plunker link for the implementation:
https://plnkr.co/edit/EimStRS1yMPbiU6PWKJN
(function () {
//factory
angular.module('app')
.factory('appFactory', ['$http', function ($http){
this.getlist = function(){
return $http.get('data.json')
.then(function(response) {
return response.data;
});
};
return this;
}]);
}());
angular.module('app').controller('appCtrl', ['$scope', '$http', '$log','$location', 'appFactory',
//controller
function($scope, $http, $log, $location, appFactory) {
// Chapters json data
appFactory.getlist()
.then(function(data) {
$scope.events = data;
});
}]);

AngularJs get data from $http before controller init

I have a simple angularjs application, in which I want to run a slider and the slider elements come from $http request.
Here is the code for reference:
var mainApp = angular.module("myapp", []);
mainApp.run(['$rootScope', '$http',
function($rootScope, $http) {
$http.post('process.php?ajax_type=getChild').success(function(data) {
if (data.success) {
console.log(data.child); // data received...
$rootScope.categories = data.child;
}
});
}]);
mainApp.controller('gridChildController', function($scope, $http, $rootScope) {
console.log($rootScope.categories); // this is also null....
$scope.brands = $rootScope.categories;
$scope.finished = function(){
jQuery('.brand_slider').iosSlider({
desktopClickDrag: true,
snapToChildren: true,
infiniteSlider: false,
navNextSelector: '.brands-next',
navPrevSelector: '.brands-prev',
lastSlideOffset: 3,
onSlideChange: function (args) {
}
});
};
});
Here is code of the template file:
<div ng-app="myapp">
<div ng-controller="gridChildController" class="brand_slider" >
<div class='slider'>
<div class="slide col-md-5ths col-sm-4 col-xs-12 text-center" ng-repeat="x in brands" ng-init="$last && finished()">
<img class="img-responsive center-block" ng-src="{{x.image}}" title="{{x.title}}" alt="{{x.title}}">
</div>
</div>
</div>
</div>
When I run this code, I get the data from the $http but ng-repeat doesn't work, and in the controller I get data null.
If you put something on $rootScope it will be also available on the child scopes. So you can bind straight to categories (no need to copy it to $scope.brands):
ng-repeat="x in categories"

Making an $http.get or $http.jsonp call in Angular.js

I was given the following code to use to get the data I need, but it is not working for me. What am I doing wrong here. I have tried many things from the Angular.js docs and other stack overflow posts, but nothing has worked for me.
someurl
header: Content-Type = application/json
Pass in the following json:
{
"userID": "SomeUSER",
"password": "SomePSWD"
}
Below is the code I am using and it is not working.
function getGroup($scope, $http) {
$http.get('SOMEURL?callback=JSON_CALLBACK&userID=SomeUSER&password=SomePSWD ').
success(function(data) {
$scope.group = data;
});
}
this angularjs demo app show how to use http.jsonp
var httpJsonDemoController = angular.module('HttpJsonDemo', []);
httpJsonDemoController.controller('DataController', ['$scope', '$http', function($scope, $http) {
$http.jsonp("http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Waseem%20Hero").
success(function(data) {
$scope.data = data;
$scope.name = data.name;
$scope.salutation = data.salutation;
$scope.greeting = data.greeting;
}).
error(function (data) {
$scope.data = "Request failed";
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<div id="wrapper" ng-app="HttpJsonDemo">
<div ng-controller="DataController">
<pre ng-model="data">
{{data}}
</pre>
<input ng-model='name' />
{{name}}
<input ng-model='salutation' />
{{salutation}}
<input ng-model='greeting' />
{{greeting}}
</div>
</div>

Reload DOM after AJAX queries AngularJS

In my project, I do an AJAX request using AngularJS who call another page that includes Angular directives (I want to make another AJAX call inside) but no interaction in loaded page.
I think new DOM isn't functionnal.. I'm trying the pseudo-code $apply unsuccessed.
Main.html :
<!DOCTYPE html>
<html data-ng-app="App">
<head></head>
<body >
<div data-ng-controller="editeurMenuMobile">
<ul>
<li data-ng-click="callMenu('FirstAjax.html')" > <!-- Work ! -->
<a href="">
<span>Modèles</span>
</a>
</li>
<li data-ng-click="callMenu('FirstAjax.html')"> <!-- Work ! -->
<a href="">
<span>Designs</span>
</a>
</li>
</ul>
<div data-ng-bind-html="data">
<!-- AJAX content -->
</div>
</div>
<!-- Javascript scripts -->
</body>
</html>
FirstAjax.html :
<div data-ng-controller="editeurActionAjax">
<div>
<button data-ng-click="callAction('SecondAjax.html')"> <!-- Doesn't work -->
Go
</button>
</div>
</div>
And my JS :
var App = angular.module('App', []);
App.controller('editeurMenuAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callMenu = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
$scope.showAjaxError = true;
});
};
}
]);
App.controller('editeurActionAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callAction = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
});
};
}
]);
Thank you for your help
From my point of view could the problem be because of the $scope?
your 2nd Controller don't have access to the same data variable.
Try to change the code to use $rootScope in both controllers instead of $scope, and see if it fix the problem.
Or
On your FirstAjax.html insert this:
<div data-ng-bind-html="data">
<!-- AJAX content -->
</div>
This should make a second data variable inside Scope of Controller 2, so that it can place the content.
I resolve my problem with this response.
My new JS :
App.directive('bindHtmlUnsafe', function( $compile ) {
return function( $scope, $element, $attrs ) {
var compile = function( newHTML ) { // Create re-useable compile function
newHTML = $compile(newHTML)($scope); // Compile html
$element.html('').append(newHTML); // Clear and append it
};
var htmlName = $attrs.bindHtmlUnsafe; // Get the name of the variable
// Where the HTML is stored
$scope.$watch(htmlName, function( newHTML ) { // Watch for changes to
// the HTML
if(!newHTML) return;
compile(newHTML); // Compile it
});
};
});
var App = angular.module('App', []);
App.controller('editeurMenuAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callMenu = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
$scope.showAjaxError = true;
});
};
}
]);
App.controller('editeurActionAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callAction = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
});
};
}
]);
And new Main.html :
<!DOCTYPE html>
<html data-ng-app="App">
<head></head>
<body >
<div data-ng-controller="editeurMenuMobile">
<ul>
<li data-ng-click="callMenu('FirstAjax.html')" > <!-- Work ! -->
<a href="">
<span>Modèles</span>
</a>
</li>
<li data-ng-click="callMenu('FirstAjax.html')"> <!-- Work ! -->
<a href="">
<span>Designs</span>
</a>
</li>
</ul>
<div data-bind-html-unsafe="data">
<!-- AJAX content -->
</div>
</div>
<!-- Javascript scripts -->
</body>
</html>
And FirstAjax.html :
<div data-bind-html-unsafe='dataAction' >
<div class="addRubrique">
<button data-ng-click="callAction('SecondAjax.html')">
Ajouter
</button>
</div>
</div>
BindHtmlUnsafe the directive re-compile the new DOM to Angular knows the DOM loaded AJAX

Categories

Resources