Data binding not working - AngularJS - angularjs

Somehow, I am unable to display the data from my backend in the component. Console logging response.data gives me my data. I put it in the movies variable within the scope, but it doesn't bind. Here is the code:
INDEX.HTML FILE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Movies - AngularJS</title>
<!-- Styles -->
<link rel="stylesheet" href="style.css">
<!-- Scripts -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl" id="app">²
<div class="box" ng-repeat="movie in movies">
<h2 ng-class="movie.genre">{{ movie.genre }}</h2>
<h1>{{ movie.title }}</h1>
<p>Change the values of the movie.</p>
<input ng-change="onChange" ng-model="movie.title" type="text">
<input ng-change="onChange" ng-model="movie.genre" type="text">
</div>
</div>
<script src="main.js"></script>
</body>
</html>
MAIN.JS FILE
const app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
axios.get(`http://localhost:3001/api/movies`)
.then(response => {
$scope.movies = response.data;
console.log($scope.movies); // logs the data correctly
})
.catch(e => console.error(e.message));
});
I think it has something to do with Async/sync'ness but I don't know how to solve it. Thanks for the help! :)

Use angular $http instead of axios to make your requests since it will internally call for view digest when you update scope within callbacks
Any time you use code outside of angular context to update scope you need to tell angular to run a digest
Also will remove axios as unnecessary dependency to load in page since $http already exists in angularjs core

I do not see any issues with your code, probably you need to force the rendering manually using $scope.$apply();
$scope.movies = response.data;
$scope.$apply();

Since you are using axios and wrapping your angular $scope inside it, the digest cycle is unable to read that change
Use, angular's $http instead of axios
OR
If you want to use axios then, you can use $scope.$apply and wrap $scope.movies = response.data; inside it.
like
$scope.$apply(function () {
$scope.movies = response.data;
});

You need to tell angularjs to update - call
$scope.$evalAsync();
after set data

Related

Possibility load Angular js page with AJAX?

I have a main page like this:
index.html
<div id="ajaxContent"></div>
<button onclick="callAjax()">Click</button>
<script>
function callAjax() {
$.ajax({
type: "POST",
url: "angular.html",
data: data,
success: function (response) {
$("#ajaxContent").html(response);
}
});
}
</script>
And in angular.html
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script>angular.module("myApp").controller("myCtrl", function ($scope) {
$scopr.test="hello!";
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
{{test}}
</div>
but after loading by ajax always says "angular is not defined" is there any way to do this?thanks.
First thing I would say, no need use jQuery for AJAX when you can use the angular's $http service.
If you want to load the whole html file based on some condition you can use a directive or angular's routing.
In my opinion it's wrong to try doing it this way, what are you trying to achieve?
I am quite sure that your problem with angular not being defined comes from the fact that you don't put the <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script> in the page where you are trying to insert this HTML.

Why doesn't dismiss-on-timeout work for ui-bootstrap's alert directive after an ngClick?

It works normally, but doesn't work after an ngClick.
Why is this?
How should this be dealt with if you do want it to work after an ngClick?
It actually works in the snippet below, but doesn't work in this Plunker, and also doesn't work in my app.
It also never works more than once in any of the three places, and I don't know why that is.
angular
.module('app', ['ui.bootstrap'])
.controller('MainController', MainController)
;
function MainController() {
var vm = this;
vm.updateSuccess = false;
vm.closeUpdateSuccess = function() {
console.log('closeUpdateSuccess');
vm.updateSuccess = false;
};
vm.submit = function() {
vm.updateSuccess = true;
};
}
<!DOCTYPE html>
<html ng-app='app'>
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script data-require="ui-bootstrap#0.13.3" data-semver="0.13.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js'></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller='MainController as vm'>
<alert ng-show='vm.updateSuccess' type='success' close='vm.closeUpdateSuccess()' dismiss-on-timeout='2000'>
Successfully updated!
</alert>
<h1>Test Text</h1>
<button ng-click='vm.submit()'>Submit</button>
</div>
</body>
</html>
The problem is you are not using the alert directive correctly. It is working as designed and you can see this by looking at the console in your browser. When the page is rendered, two seconds later your logging statement is executed. The alert directive doesn't know or care whether or not it is visible. Angular will execute the directive when it is added to the DOM. For ng-show as you are using, it is only ever added once. You could use ng-if to achieve the desired behavior or, as I say below, ng-repeat if you want the ability to display multiple alerts.
Look at our examples here and see how we're using an array to store them and the HTML code to display them via an ng-repeat.
your are using angular-ui but you are trying to execute native javascript function, try to use the angular in your js file.1 So you need to implement it with so that directive could call it,
<alert type="danger" close='closeUpdateSuccess()' ng-if="show"
dismiss-on-timeout="2000">Something happened.</alert>
and in controller:
$scope.show = true;
$scope.closeUpdateSuccess() = function(index) {
$scope.show = false;
};

Can I bind an AngularJS model to a hash URL and an HTML input at the same time?

I'm teaching myself Angular and I've looked over a number of examples that show how to bind a model to an HTML input so that they always contain the same text.
I understand that Angular also provides the $location service which works with the URL.
I have an application that I'm thinking of partially rewriting in Angular as a learning example.
In my example, I have an HTML input that I keep synced up with a model using jQuery and also synced up with a hash URL.
Is there a simple way of accomplishing this with AngularJS?
Consider the example application bellow:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script>
var myApp = angular.module('myApp', []);
function FirstController($scope, $location) {
var data = {
bar: 'hello world'
};
$scope.data = data
}
</script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="FirstController">
<input ng-model="data.bar" />
<h2>{{ data.bar }}</h2>
</div>
</div>
</body>
</html>
This is a simple example showing how the model can be kept synced with a textbox. I was wondering if it's possible to keep it synced with a hash URL, as well, so that we would have http://www.example.com#bar=What_The_User_Typed
What you probably need is the $routeProvider
https://docs.angularjs.org/tutorial/step_07

AngularJS same controller in non nested divs

I have got two separate divs as shown in the code below. What I am trying to do is update the Controller from first div and then detect the changes in the second div using the same controller. When I press the button, 'i am here' gets printed on the console but the data in 2nd div won't update. It should change to "clicked".
<html ng-app="app">
<head>
<title></title>
</head>
<body>
<h1>Divs below should not be nested</h1>
<div id="notNested1" ng-controller="Controller1">
<button ng-click="buttonClick()">Click me</button>
</div>
<div id="notNested2" ng-controller="Controller1">
<p>{{paragraph}}</p>
</div>
<script type="text/javascript" src="libs/angular/angular.js"></script>
<script>
var app = angular.module('app', []);
function Controller1($scope) {
$scope.paragraph = 'initial';
$scope.buttonClick = function () {
console.log('i am here');
$scope.paragraph = "clicked";
};
}
</script>
</body>
</html>
How can I fix this problem? Also what is the problem here? Is it because the $scope is different for both divs?
Thanks
You should probably share the data using a service/factory.
You could also create a parent controller with the data there, and reference it from the child controllers, but a shared service seems better.
Yes you have 2 separate scopes, so they do not interact with each other.

Simple angular example not working: ng-repeat + $resource + GET

I am trying to iterate with ng-repeat, using data served from a REST service. I manage to recover the data in my main.js file, but I can't get the data to be injected into the HTML.
I just started learning nodejs and angular, so it is very probable that I am not clearly getting it. I am logging twice the call to the REST service, getting the data in one of them (using a callback function) and getting a promise in the other (Which I assume happens because the call is synchronous, I didn't use any callback function here).
What I don't understand is why the HTML doesn't get the data.
Anyway, here's the code:
main.js
var myApp = angular.module('myApp', ['ngResource']);
myApp.factory('restservice', function ($resource) {
var source = $resource(
"http://rest-service.guides.spring.io/greeting/");
var data =source.get({},function(){
//this log shows the data
console.log (data);
})
return data;
});
function AvengersCtrl($scope, $resource, restservice) {
$scope.servicedata = restservice;
//this log shows the promise
console.log($scope.servicedata);
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>AngularJS Tutorials</title>
<!-- <link rel="stylesheet" href="vendor/foundation/foundation.min.css"> -->
</head>
<body>
<div ng-app="myApp">
<div ng-controller="AvengersCtrl">
<input type="text" ng-model="search.$">
<table>
<tr ng-repeat="resource in servicedata | filter:search">
<td>{{resource.id}}</td>
<td>{{resource.content}}</td>
</tr>
</table>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular-resource.js"></script>
<script type="text/javascript" src="/angular/app/main.js"></script>
</body>
</html>
Thanks in advance, regards
The code looks good to me.
The problem is the service returns a Json object instead of list.
If you wrap it with a list like this, you will see the result
$scope.servicedata = [restservice];

Resources