AngularJS - ng-repeat is not updating when adding data - javascript

I am trying to update the list of the data by getting it from the database. Each time I'll add a data, it will not update the view, the view will only be updated when I refresh the page. I have tried a few solution by using $scope.apply and rearranging the position of my code, those doesn't make a difference. What am I missing here? Below are my code:
JS
//posting post
$scope.post = function(){
$http.post('/post',$scope.post_detail)
.success(function(response){
$scope.render();
});
}
//getting post
$scope.render = function(){
$http.get('/post')
.success(function(response){
$scope.renderPost(response);
});
}
//view post
$scope.renderPost = function(response){
$scope.posts = response;
}
$scope.remove_post = function(id){
$http.delete('/post/'+id).success(function(response){
$scope.render();
});
}
$scope.render();
HTML
<div class="jumbotron text-center" ng-controller="DashboardCtrl">
<h1>{{title}}</h1>
<input type="text" ng-model="post_detail.title" />
<input type="text" ng-model="post_detail.border_color" />
<button ng-click="post(post_detail)">Post</button>
</div>
<div ng-repeat="post in posts">
<p>{{post.title}}</p>
<button ng-click="remove_post(post._id)">Remove</button>
</div>
Note: The remove button works here

Because ng-repeat is outside DashboardCtrl scope. I guess you have a parent controller of the DashboardCtrl div and the posts div and you initiate $scope.posts in the parent controller.
When you have
$scope.renderPost = function(response){
$scope.posts = response;
}
it updates the posts in the child scope. You probably need to do something like:
$scope.$parent.posts = response;
or move the ng-repeat div inside <div class="jumbotron text-center" ng-controller="DashboardCtrl">...</div>

Because you are updating only database.
push newly added post_detail into post object.
//posting post
$scope.post = function(){
$http.post('/post',$scope.post_detail)
.success(function(response){
$scope.post.push($scope.post_detail);
$scope.render();
});
}

I assume your server response to $http.get('/post') is an array of json objects
in that case that array could be nested inside data property
$scope.renderPost = function(response){
$scope.posts = response.data;
}

Related

How to avoid AngularJS ui grid showing 'no-data' message while api is loading

I have angularjs ui-grid, i used below condition to check availability of data, which means if data is not there i am showing 'no data available' message.
The problem is my api call is little slow because of huge data, so while this call in process no data available will show, I need to hide it in angular way initially. I cant use disply:none initially because there are so many conditions in grid filter after which that message will have to show, so every time i cant say disaply:none and display:block. Any help will be very helpful thank you.
html
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid">
<div class="watermark" ng-show="!gridOptions.data.length">No data available</div>
</div>
</div>
Sample js call
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json')
.success(function(data) {
data = {"data": []};
$scope.gridOptions.data = data;
});
Please see the demo in below plunker
Add a new variable in controller:
$scope.noData = false;
Change your api call as:
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500.json')
.success(function(data) {
if (data.length > 0) {
$scope.gridOptions.data = data;
} else {
$scope.noData = true;
}
});
in the view change:
<div class="watermark" ng-show="noData">No data available</div>
Test Plunker
Easy doing by using another state handler variable e.g. $scope.loading:
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid">
<div class="watermark"
ng-show="!gridOptions.data.length && !loading">No data available</div>
<div class="watermark"
ng-show="loading">loading ...</div>
</div>
</div>
Controller
$scope.loading = true;
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json').success(function(data) {
$scope.loading = false;
data = {"data": []};
$scope.gridOptions.data = data;
});
1) plnkr Demo
2) plnkr Demo (inlcuding a little timeout)

How to display a returned json in angular view?

I am implementing a search in the github repository.
I need to display the information that i get from here: https://api.github.com/search/repositories?q=bootstrap . for instance into a view or HTML
<div ng-app="newsearchApp">
<div ng-controller="MainCtrl">
<form action="#/about" method="get">
<input ng-model="searchText" />
<button ng-click="search()">Search</button>
</form>
</div>
</div>
the code for searching the Github repository;
angular.module('newsearchApp')
.controller("MainCtrl", ["$scope", function($scope) {
$scope.searchText = "";
$scope.search = function() {
console.log($scope.searchText);
var item = $scope.searchText;
// console.log(item)
var GithubSearcher = require('github-search-api');
var github = new GithubSearcher({username: 'test#something.com', password: 'passwordHere'});
var params = {
'term': $scope.searchText
};
//i am not certain about the 'userData'
github.searchRepos(params, function(data) {
console.log(data);
$scope.userData = data; //i am not certain about the 'repoData'
});
} }]);
the problem is here, when populating the json object to HTML
<div ng-repeat="repo in userData | filter:searchText | orderBy:predicate:reverse" class="list-group-item ">
<div class="row">
<div class="col-md-8">
<h4>
<small>
<span ng-if="repo.fork" class="octicon octicon-repo-forked"></span>
<span ng-if="!repo.fork" class="octicon octicon-repo"></span>
<small>{{repo.forks_count}}</small>
</small>
<a href="{{repo.html_url}}" target="_blank" >
{{repo.name}}
</a>
<small>{{repo.description}}</small>
<small>{{repo.stargazers_count}}</small>
<a href="{{repo.open_issues_count}}" target="_blank" >
Open Issues
</a>
<small>{{}}</small>
</h4>
</div>
</div>
</div>
the results are null on the HTML but are not null on the console.
thanks in advance
the results are null
The problem is, that Angular doesn't notice that the GitHub server has answered and doesn't update the view. You have to tell Angular manually to re-render the view. Try calling $scope.$apply():
github.searchRepos(params, function(data) {
console.log(data);
$scope.userData = data;
$scope.$apply();
});
If you'd make your request to the GitHub API with Angulars $http service, then this would not be needed - you'll only need $scope.$apply() if something asynchronous happens which doesnt live in the "Angular world" - for example things like setTimeout, jQuery ajax calls, and so on. That's why there are Angular wrappers like $timeout and $http.
More details: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
The GitHub API can be accessed using the AngularJS $http service:
app.controller("myVm", function($scope,$http) {
var vm = $scope;
var url = "https://api.github.com/search/repositories?q=bootstrap"
$http.get(url).then(function onSuccess(response) {
vm.data = response.data;
console.log(vm.data);
})
})
HTML
<div ng-app="myApp" ng-controller="myVm">
<div ng-repeat="item in data.items">
{{item.full_name}}
</div>
</div>
The DEMO on JSFiddle
Since you're not using the Angular $http service, angular is not aware of the changes. You need to manually tell Angular to re-render and evaluate by using
$scope.$apply();

Send ID over to angularjs - so the true content appears

I am storing an Id in a hidden field; it can also be another number such as 2, 3, 4 or 59. It must take the Id coming from the hidden field and must send it over to my opgaver.js file. where it will then download the content.
I'm stuck on how to send the Id to the opgaver.js file.
index.html
<div class="col-md-12" ng-app="Opgaver" ng-controller="OpgaverCheck">
<input type="hidden" value="1" ng-model="Id" />
<div ng-repeat="Value in Newslist">
</div>
</div>
Opgaver.js
var app = angular.module('Opgaver', []);
app.controller('OpgaverCheck', function ($scope, $http) {
//GET
var url = "/opgaver/kategori/"; //Id HERE//
$http.get(url).success( function(response) {
$scope.Newslist = response;
});
});
The problem is: How to get my Id over to opgaver.js so content can appear there.
Your HTML should be like
<input type="text" ng-init="Id='1'" ng-model="Id" />
And inside your controller:
$scope.$watch("Id", function() {
var url = "/opgaver/kategori/" + $scope.Id;
$http.get(url).success( function(response) {
$scope.Newslist = response;
});
});
I think you are missing the whole concept of angular and it's magic. Double binding you declare something in view in ng-module and you have access in the JavaScript withing $scope or the other hand you declare something in JavaScript within $scope and have in view in ng-module
From JS
$scope.myVariable = "I will meat you in view";
In Html
ng-module="myVariable" or {{myVariable}}
When you set ng-model="Id" in your field you had the access of that variable on scope.
In JS
var url = "/opgaver/kategori/" + $scope.Id;

Can't get the datas in angularJs

I have html page like
<div ng-controller="userListControl">
...
</div>
<div ng-controller="userDetailsControl">
....
</div>
And i have angular Js code is
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", ['$scope','$http', function($scope, $http)
{
$http.get('data/userData.json').success (function(data){
$scope.users = data;
$scope.users.doClick = function(user,event) {
userInfo(user);
}
});
}]);
function userInfo(users)
{
console.log(user);
userDirectory.controller("userDetailsControl", function($scope)
{
console.log('well')
$scope.user = users;
console.log($scope.user)
});
}
Here Everything is working fine. But when we are calling click event, That userInfo called with particular Data. But Second controller gives an error(angular js Error).
I am new one in angular jS. I dont know this logic is correct or not.
I have list items in first Controller. When we are clicking on list, It gets data from particular list and passed to another design. That design have detailed data. So the 2nd controller shows particular list detailed Section
First, There is no need to declare your controller inside a function - I don't think that you're trying to lazy-load controllers. Make it available to your app when it starts.
Second, you need to pass data to the userDetailsControl controller. There are various ways to do this, but here you could just use the $rootScope.
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", function($scope, $rootScope, $http)
{
$scope.selectUser = function(user){
$rootScope.selectedUser = user;
}
$http.get('data/userData.json')
.success (function(data){
$scope.users = data;
});
})
.controller("userDetailsControl", function($scope, $rootScope){
$rootScope.$watch("selectedUser", function(newVal){
$scope.user = newVal;
}
}
and in your HTML:
<div ng-controller="userListControl">
<button ng-repeat="user in users" ng-click="selectUser(user)">{{user.name}}</button>
</div>
<div ng-controller="userDetailsControl">
<div>{{user.name}}</div>
<div>{{user.otherDetails}}</div>
</div>

AngularJS Push New Data into Specific JSON

I've got a JSON output that looks like this:
[{"id":"121","title":"Blog Title","content":"Blog content"}, "comments":[{"id":"12","content":"This is the comment."}]]
I'm retrieving the array through a controller in Angular:
app.controller('BlogController', function($scope, $http) {
var blog = this;
blog.posts = [];
$http.get('/process/getPost.php').success(function (data) {
blog.posts=data;
});
$scope.submitComment = function() {
blog.posts.concat($scope.formData);
$http({
method : 'POST',
url : '/process/insertComment.php',
data : $.param($scope.formData), // pass in data as strings
headers: {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.success(function(data) {
console.log(data);
$scope.formData.comment="";
});
};
})
Then displaying the information in my index.html file:
<div ng-controller="BlogController as blog" ng-cloak class='ng-cloak'>
<div ng-repeat="post in posts">
<div>{{post.title}}</div>
<div>{{post.content}}</div>
</div>
<div ng-repeat="comment in post.comments">
{{comment.content}}
</div>
<form name="commentform" ng-init="formData.id=post.id" novalidate>
<textarea ng-model="formData.comment" name="comment" required></textarea><br>
<input type="submit" ng-disabled="commentform.$invalid" value="Submit" ng-click="submitComment()">
</form>
</div>
Everything works as it should but I've been trying to have the submitComment() update comment.content inside JSON array where the blog id equals post.id and where the comment id equals comment.id.
I've tried doing blog.post.comment.push($scope.formData) but that didn't work. Any idea why it doesn't work and how to fix it?
That might help you http://jsbin.com/fatote/2/edit?html,js,output
$scope.submitComment = function(post) {
$http.post('/process/insertComment.php', post.formData)
.then(function(data) {
console.log(data);
$scope.formData.comment="";
}, function(){
alert("Can't post");
}).then(function(){
//finally as we know that post would work in that case
//find last comment id
var newCommentId = post.comments[post.comments.length-1].id +1;
//create new comment obj
var newComment = {
id:newCommentId,
content:post.formData.comment
};
//push comment in comments array
post.comments.push(newComment);
//clean form
post.formData.comment="";
});
};
Your line blog.posts.concat($scope.formData); isn't being assigned anywhere. Note that .concat is different from .sort in that you're creating a new array.
From MDN: "The concat() method returns a new array comprised of this array joined with other array(s) and/or value(s)."
Try changing your line to blog.posts = blog.posts.concat($scope.formData);
edit:
I'm guessing at your data format, more likely the change needed is:
var post = blog.posts[blogPostId]; // you'll need to determine blogPostId
post.comments = post.comments.concat($scope.formData);

Categories

Resources