View doesn't get updated after a $http.get() response - angularjs

I was just following a tutorial in which a factory makes a $http.get() request and returns data which is affected to a controller's $scope variable ($scope.classifieds which is supposed to be shown in an ng-repeat loop) and the view doesn't get updated when the variable gets changed (logging the variable shows the data is successfully returned)
The view code is :
<!DOCTYPE html>
<html>
<head>
<title>Hello World!!!</title>
<link rel="stylesheet" type="text/css" href="node_modules/angular-material/angular-material.min.css">
<link rel="stylesheet" type="text/css" href="node_modules/mdi/css/materialdesignicons.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body ng-app="ngClassifieds" ng-controller="classifiedsCtrl">
<hello-world></hello-world>
<md-toolbar>
<div class="md-toolbar-tools">
<p><strong>ngClassifieds</strong></p>
<md-button>
<md-icon class="mdi mdi-plus-circle"></md-icon>
New Classifieds
</md-button>
</div>
</md-toolbar>
<md-content class="md-padding" layout="row" layout-wrap>
<md-card ng-repeat="class in classifieds" flex="30">
<img ng-src="{{ class.img }}"></img>
<md-card-content>
<div class="classified-info" ng-show="!showContact">
<h2 class="md-title">{{ class.title}}</h2>
<h3>{{ class.price | currency }}</h3>
<h4>{{ class.pdate | date : "MMMM d, y"}}</h4>
<p>{{ class.desc }}</p>
</div>
<div class="classified-contact" ng-show="showContact">
<p><md-icon class="mdi mdi-account"></md-icon> {{class.contact.name}}</p>
<p><md-icon class="mdi mdi-phone"> </md-icon> {{class.contact.phone}}</p>
<p><md-icon class="mdi mdi-email"> </md-icon> {{class.contact.email}}</p>
</div>
<div layout="row">
<md-button ng-click="showContact = true">Contact</md-button>
<md-button ng-click="showContact = false">Details</md-button>
</div>
</md-card-content>
<md-card>
<md-content>
<script type="text/javascript" src="node_modules/angular/angular.js"></script>
<script type="text/javascript" src="node_modules/angular-animate/angular-animate.js"></script>
<script type="text/javascript" src="node_modules/angular-aria/angular-aria.js"></script>
<script type="text/javascript" src="node_modules/angular-material/angular-material.js"></script>
<script type="text/javascript" src="scripts/app.js"></script>
<script type="text/javascript" src="components/classifieds.ctrl.js"></script>
<script type="text/javascript" src="components/classifieds.fac.js"></script>
</body>
</html>
the controller :
(function(){
"use strict";
angular.module("ngClassifieds")
.controller("classifiedsCtrl", ["$scope", "$http", "classifiedsFactory", function($scope, $http, classifiedsFactory){
$scope.message = "'with this dynamic text'";
$scope.classifieds = classifiedsFactory.getClassifieds().then(function(classified){
return classified.data;
});
console.log('----->>> $scope.classifieds : ' + JSON.stringify($scope.classifieds));
}] );
})();
and the factory :
(function(){
"use strict";
angular.module("ngClassifieds").factory("classifiedsFactory", function($http){
function getClassifieds() {
return $http.get('data/classifieds.json');
}
return {
getClassifieds : getClassifieds
}
});
})();
I have seen many alike questions but didn't find an answer to this problem.

$http.get() is an asynchronous, you should assign the value in success callback method.
Use
classifiedsFactory.getClassifieds().then(function(classified){
$scope.classifieds = classified.data;
});
Instead of
$scope.classifieds = classifiedsFactory.getClassifieds().then(function(classified){
return classified.data;
});

Related

Got error failed to instantiate module gupaApp due to" after include include ng-material in AnguarJS?

I have created the website using angularjs and i have used angular-material in our website but i have properly included the script file properly but i got error after inlcude the ['ngMaterial'] as a depedency in our module i dont understand what the wrong in my code.
var app = angular.module("gupaApp", ['ngMaterial']);
app.controller("gupaContr", function($scope) {
console.log('hii');
})
<html ng-app="gupaApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<link rel="stylesheet" href="https://gitcdn.xyz/repo/angular/bower-material/master/angular-material.css">
<script src="https://gitcdn.xyz/repo/angular/bower-material/master/angular-material.js"></script>
<script type="text/javascript" src="app/controller/gupaController.js"></script>
<body ng-controller="gupaContr">
<md-toolbar md-scroll-shrink>
<div class="md-toolbar-tools">
<div flex="50">
<h3 class="title"><span>My Title</span></h3>
</div>
<div flex="50" layout layout-align="end center">
<md-button class="md-fab" aria-label="Time">
<md-icon icon="/img/icons/ic_access_time_24px.svg" style="width: 24px; height: 24px;"></md-icon>
</md-button>
</div>
</div>
</md-toolbar>
</body>
</html>
You need to add references to the angular-animate.js and angular-aria.js aswell
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-aria.js"></script>
Make sure to match the version you're using
PLUNKER DEMO

ng-click doesn't work with md-button

My html and javascript are as follows, I have the following element
<i class="material-icons" ng-click="clicked()" md-48>add_circle</i>
Which works when clicked i.e. by bringing up a dialog, however the following on the same page does not work.
html
<body ng-cloak>
<div ng-cloak ng-controller="mainController" >
<div layout="row" layout-align="end end">
<md-button aria-label="Eat cake" ng-click="clicked()"></md-button>
</div>
</div>
</body>
angular
angular.module('notifyMe', ['ngMaterial', 'material.svgAssetsCache'])
.controller('mainController', function($scope, $mdDialog) {
$scope.clicked = function () {
alert('Worked!');
};
})
No, your code should work. Make sure you loaded the dependencies as below:
DEMO
// Code goes here
angular.module('webapp', ['ngMaterial'])
.controller('AppCtrl', function($scope) {
$scope.clicked = function () {
alert('Worked!');
};
});
<!DOCTYPE html>
<html ng-app="webapp">
<head>
<link rel="stylesheet" href="https://rawgit.com/angular/bower-material/master/angular-material.min.css">
<link rel="stylesheet" href="style.css" />
<!-- Angular Material Dependencies -->
<script src="//cdn.jsdelivr.net/hammerjs/2.0.4/hammer.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-aria.min.js"></script>
<!-- Use dev version of Angular Material -->
<script src="https://rawgit.com/angular/bower-material/master/angular-material.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="AppCtrl">
<div layout="column" layout-fill flex style="max-height:100%">
<md-toolbar>
<md-button ng-click=clicked()>Click here</md-button>
</md-toolbar>
</div>
</body>
</html>

Angular material autocomplete z-index issue

I'm trying to create an autocomplete feature but I can't display the results as I want, I think it's a z-index issue, but I couldn't solve it.
I can use md-autocomplete, it doesn't have this problem, but I want to learn what's causing this.
As soon as I start typing, my input goes up and results are displayed below in the navigation bar.
I changed $http to an array to mock the results.
Here's my code:
<html lang="en">
<head>
<style>
#testing > div > div > div > md-input-container {
margin:0;
}
</style>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
</head>
<body ng-app="BlankApp" ng-cloak>
<md-content>
<md-toolbar id="testing">
<div layout-wrap layout="row">
<div ng-controller="SearchCtrl" class="md-toolbar-tools">
<div flex="40" layout-align="center">
<md-input-container class="" flex="" layout="row">
<label class="search-color">Search</label>
<input ng-model="searchInput" class="text1" type="text">
</md-input-container>
<md-item-template flex="100" layout="column">
<div ng-repeat="a in details">
<div>{{a}}</div>
</div>
</md-item-template>
</div>
</div>
</div>
</md-toolbar>
</md-content>
<!-- Angular Material requires Angular.js Libraries -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<!-- Your application bootstrap -->
<script type="text/javascript">
angular.module('BlankApp', ['ngMaterial']);
angular.module('BlankApp').controller('SearchCtrl', ["$scope", "$http",
function($scope, $http) {
//$scope.searchInput = "";
$scope.$watch('searchInput', function() {
if ($scope.searchInput) {
fetch();
}
});
function fetch() {
var arr = ["result1", "result2", "result3", "result4"];
$scope.details = arr;
}
}]);
</script>
</body>
</html>
Here's my plunk : http://plnkr.co/edit/LQ1HxV6vmPkUGYHnVfCg?p=preview

Angular ng-repeat and Bootstrap column not working

I have a ng-repeat that is displaying a list of items. I want them to be a col width of 2
This is the index.html body
index.html
<!DOCTYPE html>
<html ng-app="games">
<head>
<title>Games</title>
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
<link rel="stylesheet" type="text/css" href="/static/css/fontello.css">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<meta name=viewport content="width=device-width, initial-scale=1">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="/static/app/app.js"></script>
<meta name=viewport content="width=device-width, initial-scale=1">
</head>
<body ng-controller="gamesCtrl">
<a ui-sref="games">Games</a>
<div class="container">
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
</html>
And here is the HTML I am pulling for the ui-view
list.html
<div ng-repeat="game in games">
<div ng-class="col-xs-2">
{{ game.title }}
<img src="{{game.thumbnailUrl100}}"/>
</div>
</div>
What's happening though is its just stacking everything on top of each another and not putting it next to each other.
Here is the inspect element code
<div class="row">
<!-- uiView: -->
<div ui-view="" class="ng-scope">
<!-- ngRepeat: game in games -->
<div ng-repeat="game in games" class="ng-scope">
<div class="ng-binding">Cut The Rope</div>
<img src="https://az680633.vo.msecnd.net/thumbnail/40071/100/40071.png">
</div>
<!-- end ngRepeat: game in games -->
<div ng-repeat="game in games" class="ng-scope">
<div class="ng-binding">Cut The Rope: Time Travel</div>
<img src="https://az680633.vo.msecnd.net/thumbnail/40072/100/40072.png">
</div>
</div>
Just incase something else is wrong here is the js
angular.module('games', ['ui.router', 'ui.bootstrap'])
.config(function($urlRouterProvider, $locationProvider, $stateProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/");
//take out #
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
// Now set up the states
$stateProvider
.state('games', {
url: "/",
templateUrl: "/static/app/list.html",
controller: 'gamesCtrl'
})
})
.controller('gamesCtrl', ['$scope', '$state', 'gamesFactory',
function($scope, $state, gamesFactory) {
$scope.$state = $state;
$scope.games = null;
function init() {
gamesFactory.getGames().success(function(games) {
$scope.games = games.data;
console.log($scope.games.data)
});
}
init();
}
])
.factory('gamesFactory', function($http) {
var factory = {};
factory.getGames = function() {
return $http.get('/games.json');
};
return factory;
});
ng-class is expecting an Angular expression. In this case, you are giving it the actual CSS class name. Angular tries to evaluate that as an expression, which results in undefined (or null or the empty string).
Since you don't need to do anything but apply the class name here, just use the regular class attribute instead of ng-class:
<div ng-repeat="game in games">
<div class="col-xs-2">
{{ game.title }}
<img src="{{game.thumbnailUrl100}}"/>
</div>
</div>
ng-class expects an expression. Change your markup like this:
<div ng-repeat="game in games">
<div ng-class="'col-xs-2'">
{{ game.title }}
<img src="{{game.thumbnailUrl100}}"/>
</div>
</div>
https://docs.angularjs.org/api/ng/directive/ngClass
The problem is that you're repeating the div around the columns, not the columns themselves. Try this:
<div class="col-xs-2" ng-repeat="game in games">
{{ game.title }}
<img src="{{game.thumbnailUrl100}}"/>
</div>
Try using ng-src on your image. At the time the page is first rendered, the image size probably can't be determined.
Edit, so the complete html should be:
<div ng-repeat="game in games">
<div class="col-xs-2">
{{ game.title }}
<img src= "" ng-src="{{game.thumbnailUrl100}}"/>
</div>
As others have pointed out, you shouldn't be using ng-class here.

Reader Excercise in Codecademy do not work

my code seems ok but i cannot view the html using angularjs (exercise "reader" in codecademy course")
according to my knowledge seems to be working but I am beginner so likely i have to do some tweaking
here my codes
<!doctype html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,700,300,900' rel='stylesheet' type='text/css'>
<link href="https://s3.amazonaws.com/codecademy-content/projects/bootstrap.min.css" rel="stylesheet" />
<link href="css/main.css" rel="stylesheet" />
<script src="js/vendor/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.28/angular-route.min.js"></script>
</head>
<body ng-app="ReaderApp">
<div class="header">
<div class="container"> Reader </div>
</div>
<div class="main">
<div class="container">
<div ng-view></div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/BookshelfController.js"></script>
<script src="js/controllers/BookController.js"></script>
<script src="js/controllers/ChapterController.js"></script>
<!-- Services -->
<script src="js/services/books.js"></script>
</body>
</html>
the service
app.factory('books', ['$http', function($http) {
return $http.get('https://s3.amazonaws.com/codecademy-content/courses/ltp4/books-api/books.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
the view (routed)
<div class="bookshelf row">
<!-- TODO: Loop through myBooks and display each one with this HTML -->
<div class="book col-md-3" ng-repeat="book in myBooks">
<a href="#/books/{{$index}}"> <img ng-src="{{ book.cover }}" />
<h3 class="title">{{ book.title }} </h3>
<p class="author"> {{ book.author }} </p>
</a>
</div>
</div>
controller
app.controller('BookshelfController', ['$scope','books', function($scope, books) {
books.success(function(data) {
$scope.myBooks = data;
});
}]);
and the module that create the app
var app = angular.module('ReaderApp', ['ngRoute ']);
app.config(function ($routeProvider) {
$routeProvider
.when('/books', {
controller: 'BookshelfController',
templateUrl: 'views/bookshelf.html'
})
.otherwise({
redirectTo: '/books'
});
});
thanks
Paolo
Typo in module dependency array.
var app = angular.module('ReaderApp', ['ngRoute ']);
^ remove this space!

Resources