I just deployed a website to test in "production" but when i try to go to the website some of my computer won't see one the results of my ng-repeat and some will see. If I go to the website when there's nothing displayed I look at the source code and I see the ng-repeat with each object of my array, but no html output on the screen. Here some of my code when I load my controller:
/**
* Function that send a request to get a list of posts.
* #return {Function} A promise.
*/
function retrievePosts() {
var defered = $q.defer();
// If the user is logged in we do a search by country, otherwise we get all the posts.
if($rootScope.user !== null && $rootScope.user !== undefined) {
PostService.searchPost({ countries: [$rootScope.user.country] }, function(err, posts) {
if(err) {
defered.reject(err);
}
else if(posts && posts.length > 0) {
defered.resolve(posts);
}
// If the previous condition is not true, we try to get all the posts, since the search by country didn't work.
else {
PostService.getAllPosts(function(err, posts2) {
if(err) {
defered.reject(err);
} else {
defered.resolve(posts2);
}
});
}
});
} else {
PostService.getAllPosts(function(err, posts) {
if(err) {
defered.reject(err);
}
else {
defered.resolve(posts);
}
});
}
return defered.promise;
}
This function is used to get an array of JSON posts object. Then I do a q.all like this:
$q.all([retrieveManufacturer(), retrieveCategories(), retrievePosts(), getTotalPosts(), retrieveGalleryPosts()]).then(function(results) {
$scope.manufacturers = results[0];
$scope.categories = results[1];
// Here we must cache the result and slice it, so that angular doesn't render
// a tone of post but 10 at a time.
postCache = results[2];
$scope.numberOfPostsToShow = 10;
$scope.posts = postCache.slice(0, $scope.numberOfPostsToShow);
// Some code to display the proper amount of post for each category.
var i = -1;
var max = results[3].length;
var groupedPostsCount = { };
var group;
while(++i < max) {
group = results[3][i];
// "_id" contains the name of the category.
groupedPostsCount[group._id] = group.count;
}
if(Object.keys(groupedPostsCount).length > 0){
$scope.categoriesPostCount = groupedPostsCount;
}
$scope.galleryPosts = results[4];
// Prepare the $scope.galleryPosts to be bound with posts.
buildGallery($scope.galleryPosts);
}, function(err) {
console.log(err);
});
Every task in $q.all gets executed and they all get resolved. I see them in my HTML like the categories, manufacturers, etc... Results[2] which are the array of posts are not null they really do have 500 posts in them. I try to call $scope.$apply() after buildGallery() method call, but nothing work. If I print {{ posts }} anywhere in my html i see the array of posts. But when they are in that ng-repeat:
<div class="ad-container" ng-repeat="post in posts" ng-click="viewPostDetails(post)">
<div class="ad-picture">
<table class="wrapper">
<tr>
<td><img ng-src="img/175/{{ post.mainImageName || post.imgUrls[0] }}" alt="No image provided"/></td>
</tr>
</table>
</div>
<div class="ad-info">
<span class="ad-info-title">{{ post.title }}</span>
<span class="ad-info-price">{{ post.country == 'Canada' ? (post.price | currency : "CA$") : (post.price | currency : "US$") }}</span>
<br />
<span>{{ post.country }}, {{ post.province }}, {{ post.createdAt | date }}</span>
<p>{{ post.description }}</p>
</div>
</div>
Of course this code is inside a div that has a controller bound to it.Like I said, it's really weird. On my development computer everything works perfectly, but some of the computers of my friend did work and others didn't. Here's the link to the website www.firearmsbin.com maybe the problem will occur on your computer. I tried on firefox, firefox for dev, edge, chrome and IE11.
Thanks.
I found out that it was adblock who was not displaying my div which as the class "ad-container". So every class in css that contains "ad" word get block.
Related
I have a dating project. We are using laravel 6 and jquery 3.4.1
The problem is that I need to draw a div when receiving AJAX.
So, javascript and blade template :
static countNewMessages() {
$.get('/some/link/here', results => {
let total = 0;
if (results.length === 0) {
$('.chat__list-block').each(function (index) {
$(this).removeClass('chat__list-block_new');
});
$('.chat__list-non-read-counter').addClass('chat__list-non-read-counter_hidden').each(function (index) {
$(this).text('');
});
$('#number-of-new-messages').addClass('d-none').removeClass('d-flex').html('');
$('#inbox-messages-count-title').html('0');
return false;
}
results.forEach(v => {
if (Chat.containers?.threads) {
let threadElement = $('.chat__list-block[data-pid=' + v.from_userid + ']');
threadElement.addClass('chat__list-block_new');
threadElement.find('.chat__list-non-read-counter')
.addClass('chat__list-non-read-counter_hidden')
.text(v.count);
if (0 < threadElement.length && !threadElement.hasClass('chat__list-block_active') && 0 < v.count) {
threadElement.find('.chat__list-non-read-counter')
.removeClass('chat__list-non-read-counter_hidden');
}
}
total += v.count;
$('#number-of-new-messages').addClass('d-flex').removeClass('d-none').html(total);
$('#inbox-messages-count-title').html(total);
});
});
}
#if(count($threads))
<div>Chat requests</div>
#else
<div>No chat requests</div>
#endif
The standard if-else behavior in the template suits me fine. If a user visits the page but has no messages the second block is displayed, and if he has messages the first block is displayed. But if a user who is on the block "no chat requests" and receives new messages then the block "chat requests" is rendered only after a full refresh of the page.
If you need more information, please let me know
Try this :
#if(count($threads))
<div data-threads-count="{{ count($threads) }}">Chat requests</div>
#else
<div data-threads-count="{{ count($threads) }}">No chat requests</div>
#endif
Now you can access threads count by using data function in jquery ex :
$(selector).data('threads-count');
or
$(selector).attr('data-threads-count');
Both will return threads count
i hope it was useful 😊
I am starting with a simple TODO app with Aurelia, RethinkDB & Socket.IO. I seem to have problem with re-rendering or re-evaluating an object that is changed through Socket.IO. So basically, everything works good on the first browser but doesn't get re-rendered in the second browser while displaying the object in the console does show differences in my object. The problem is only on updating an object, it works perfectly on creating/deleting object from the array of todo items.
HTML
<ul>
<li repeat.for="item of items">
<div show.bind="!item.isEditing">
<input type="checkbox" checked.two-way="item.completed" click.delegate="toggleComplete(item)" />
<label class="${item.completed ? 'done': ''} ${item.archived ? 'archived' : ''}" click.delegate="$parent.editBegin(item)">
${item.title}
</label>
<i class="glyphicon glyphicon-trash"></i>
</div>
<div show.bind="item.isEditing">
<form submit.delegate="$parent.editEnd(item)">
<input type="text" value.bind="item.title" blur.delegate="$parent.editEnd(item)" />
</form>
</div>
</li>
</ul>
NodeJS with RethinkDB changefeeds
// attach a RethinkDB changefeeds to watch any changes
r.table(config.table)
.changes()
.run()
.then(function(cursor) {
//cursor.each(console.log);
cursor.each(function(err, item) {
if (!!item && !!item.new_val && item.old_val == null) {
io.sockets.emit("todo_create", item.new_val);
}else if (!!item && !!item.new_val && !!item.old_val) {
io.sockets.emit("todo_update", item.new_val);
}else if(!!item && item.new_val == null && !!item.old_val) {
io.sockets.emit("todo_delete", item.old_val);
}
});
})
.error(function(err){
console.log("Changefeeds Failure: ", err);
});
Aurelia code watching Socket.on
// update item
socket.on("todo_update", data => {
let pos = arrayFindObjectIndex(this.items, 'id', data.id);
if(pos >= 0) {
console.log('before update');
console.log(this.items[pos]);
this.items[pos] = data;
this.items[pos].title = this.items[pos].title + ' [updated]';
console.log('after update');
console.log(this.items[pos]);
}
});
// create item, only add the item if we don't have it already in the items list to avoid dupes
socket.on("todo_create", data => {
if (!_.some(this.items, function (p) {
return p.id === data.id;
})) {
this.items.unshift(data);
}
});
// delete item, only delete item if found in items list
socket.on("todo_delete", data => {
let pos = arrayFindObjectIndex(this.items, 'id', data.id);
if(pos >= 0) {
this.items.splice(pos, 1);
}
});
The socket.on("todo_update", ...){} is not making the second browser re-render but showing the object in the console before/after update does show differences in the object itself. I even changed the todo title property and that too doesn't get re-rendered.
How can I get Aurelia to re-render in my second browser with the new object properties? Don't be too hard on me, I'm learning Aurelia/RethinkDB/NodeJS/Socket.IO all the same time...
Aurelia observes changes to the contents of an array by overriding the array's mutator methods (push, pop, splice, shift, etc). This works well for most use-cases and performs really well (no dirty-checking, extremely lightweight in terms of memory and cpu). Unfortunately this leaves one way of mutating an array that aurelia can't "see": indexed assignment... eg myArray[6] = 'foo'. Since no array methods were called, the binding system doesn't know the array changed.
In your case, try changing this:
// update item
socket.on("todo_update", data => {
let pos = arrayFindObjectIndex(this.items, 'id', data.id);
if(pos >= 0) {
console.log('before update');
console.log(this.items[pos]);
this.items[pos] = data; // <-- change this to: this.items.splice(pos, 1, data);
this.items[pos].title = this.items[pos].title + ' [updated]';
console.log('after update');
console.log(this.items[pos]);
}
});
I am trying to implement a simple favorites system. On the page load posts are listed on the home page and any previously favorited posts called nubs will show up with the FAVED tag underneath them.
<div class="list-group" ng-repeat="nub in nubs">
<a href="#" class="list-group-item active">
<h4 class="list-group-item-heading">{{nub.title}}</h4>
<p class="list-group-item-text">{{nub.description}}</p>
<p class="list-group-item-text">{{nub.synopsis}}</p>
<li ng-repeat="url in nub.attachmentsUrls">
<p class="list-group-item-image">
<img ng-src={{url}} />
</p>
</li>
</a>
<button ng-click="toggleFav(nub)">favorite</button>
<p ng-show="getFaved(nub.$id)">FAVED</p>
</div>
This is working but when I add something to my favorites the page doesn't update to reflect the newly favorited post. I would like to make my page respond actively to the toggleFav function.
Here is my controller
var ref = new Firebase("https://xxxxx.firebaseio.com");
var auth = ref.getAuth();
var nubRef = new Firebase("https://xxxxx.firebaseio.com/Nubs");
var nubs = $firebaseArray(nubRef);
$scope.nubs = nubs;
var userRef = new Firebase("https://xxxxx.firebaseio.com/users");
var users = $firebaseArray(userRef);
$scope.users = users;
// Array of booleans for favorites
$scope.favedArray = [];
// Array of user ids for
$scope.userIdArray = [];
var userFavs = $firebaseArray(userRef.child(auth.uid).child("favorites"));
$scope.userFavs = userFavs;
userFavs.$loaded()
.then
(
function()
{
nubs.$loaded()
.then
(
function()
{
$scope.tempFaved = [];
$scope.tempId = [];
console.log(userFavs);
angular.forEach
(
nubs,
function(nub)
{
$scope.tempFaved.push(false);
$scope.tempId.push(nub.$id);
console.log($scope.tempId);
angular.forEach
(
userFavs,
function(favs)
{
console.log($scope.tempFaved);
if(favs.nub == nub.$id)
{
$scope.tempFaved.pop();
$scope.tempFaved.push(true);
console.log($scope.tempFaved);
}
}
);
}
);
while($scope.tempFaved.length > 0)
{
$scope.favedArray.push($scope.tempFaved.pop());
$scope.userIdArray.push($scope.tempId.pop());
}
$scope.getFaved = function(nubId)
{
console.log($scope.favedArray[$scope.userIdArray.indexOf(nubId)]);
$scope.faved = $scope.favedArray[$scope.userIdArray.indexOf(nubId)];
return $scope.faved;
}
$scope.toggleFav = function(nub)
{
var nubFavRef = nubRef.child(nub.$id).child("favorites");
var nubFavs = $firebaseArray(nubFavRef);
var faved = $scope.getFaved(nub.$id)
console.log(faved);
if (faved == false)
{
nubFavs.$add
(
{
user: auth.uid
}
);
userFavs.$add
(
{
nub: nub.$id
}
)
console.log("favorited");
}
else
{
nubFavs.$remove(auth.uid);
userFavs.$remove(nub.$id);
console.log("unfavorited");
}
};
}
)
}
);
Essentially it is looping through the nubs or posts displayed on the page and checking them against the nubs the user has favorited to display the FAVED tag and toggle the functionality of the favorite button. If the user doesn't have the nub favorited the button will add the nub to their list of favorites as well as adding them to the list of users that have the nub favorited and if the user does have the post favorited it will remove them.
The unfavorite functionality of the toggleFav doesn't work either so help with that would also be appreciated, but that's a matter of being able to access the right child of the faved arrays which I'm not sure how to do.
What I think needs to happen for the page to update with the right information when something is favorited is some kind of $on listener, but I'm not sure how to implement it.
/* How store data in fire base:
{
"home" : {
"room1" : {
"status" : "true",
"switch_name" : "light 2",
"user_id" : "-Kvbk-XHqluR-hB8l2Hh"
}
}
}
*/
//select element in which you want real time data.
const preObject = document.getElementById('tbl_switch_list');
//select your root table name
const dbRefObject = firebase.database().ref().child('home');
//Change Value in Firebase and view in your console.
dbRefObject.on('value',snap => console.log('Response : ',snap.val());
<h3>Switch List</h3>
<table id="tbl_switch_list" border="1">
<thead>
<tr>
<td>#ID</td>
<td>#switchName</td>
<td>#status</td>
</tr>
<thead>
<tbody id="list"></tbody>
</table>
How to Write Condition on data which is fetching from Json to Angularjs?
Example : if user FIRM NAME exists Show else if user FULL NAME exists Show else Show REALNAME
I have a working Example of fetching data
at line number 25 <h3 class="moduletitle">Name : {{ module.realname }}</h3>
Please See that in PLUNKER
I hope i will get the working code update along with PLUNKER
I can suggest you have a function that returns the entity in which you want to display. Then using ng-show / ng-hide to display/hide the things you want.
Example:
function pseudoDecide(){
var displaythis = "";
if(/*boolean exp*/){ displaythis = "firm" }
else if(/*boolean exp*/) { displaythis = "full" }
else(/*boolean exp*/) { displaythis = "real" }
return displaythis;
}
Then <div ng-show="{{psedoDecide() === 'firm'}}>" etc etc, something like that.
With AngularJS 1.1.5+, you can use the ternary operator inside an expression. In your case, I believe you want something like:
<h3 class="moduletitle">Name : {{ module.firmname ? module.firmname : (module.fullname ? module.fullname : module.realname)) }}</h3>
If you don't want a nested ternary in your template, you could also go this route:
Somewhere in your controller:
$scope.pickName = function (module) {
var val;
if (module.firm_name) {
val = module.firm_name;
} else if (module.full_name) {
val = module.full_name;
} else {
val = module.realname;
}
return val;
};
And in your template:
<h3 class="moduletitle">Name : <span ng-bind="pickName(module)"></span></h3>
I followed information on this answer
But it doesn't work in my situation.
Chrome Inspector console says "ReferenceError: dataResponse is not defined"
maybe that is the problem?
I am trying to GET this JSON from url:
[{"app_id":1,"app_name":"oh yeeah","app_description":"desc","app_price":111,"is_activated":false,"video":"videolink"},{"app_id":2,"app_name":"oh yeaaaeah","app_description":"ewaewq","app_price":222,"is_activated":false,"video":"fuck off"},{"app_id":3,"app_name":"oh yeaaaeah","app_description":"ewaewq","app_price":333,"is_activated":false,"video":"fuck off"}]
This is my javascript code
var appstore = angular.module('appstore', []);
appstore.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function(callbackFunc) {
$http({
method: 'GET',
url: '/administrator/components/com_apps/loadAppsJson.php'
}).success(function(data){
callbackFunc(data);
}).error(function(){
alert("error");
});
}
});
appstore.controller('app_Ctrl', function($scope, dataService) {
$scope.apps = [
{app_id:1, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
{app_id:2, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
{app_id:3, app_name:'oh yeah', app_description:'$app_description', app_price:111, is_activated:false, video:'$videolink'},
];
//$scope.apps = null;
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
});
console.log(dataResponse);
console.log($scope.apps);
//get images thumbs
for(app = 0; app <= $scope.apps.length-1; app++) {
$scope.apps[app].thumb = ("000" + $scope.apps[app].app_id).slice(-3);
}
//separate apps to columns
var columns = [];
for (var i = 0; i < $scope.apps.length; i++ ) {
if (i % 3 == 0) columns.push([]);
columns[columns.length-1].push($scope.apps[i]);
}
$scope.columns = columns;
});
My HTML view
<div ng-controller="app_Ctrl">
<div class="row"></div>
<div class="row">
<div class="row" ng-repeat="apps in columns">
<div id="app_id_{{ app.app_id }}" class="col-lg-4" ng-repeat="app in apps | filter:search">
<div class="thumbnail" ng-class="app.is_activated ? 'activated' : ''">
<!-- -->
<img ng-src="/images/apps/app_images/{{ app.thumb }}_thumb.jpg" alt="{{ app.app_name }}" title="{{ app.app_name }}">
<div class="caption">
<h3>{{ app.app_name }}</h3>
<p class="app_price">{{ app.app_price }} €</p>
<div style="clear:both;"></div>
<p class="app_card_description">{{ app.app_description | limitTo:100 }}...</p>
Info
Video <span class="glyphicon glyphicon-facetime-video"></span>
{{ app.is_activated ? 'Aktivované' : 'Aktivovať' }}
</div>
</div>
</div>
</div>
To elaborate on what #Mritunjay said in the comments; review this code with comments:
dataService.getData(
// this is your callback function which has an argument for dataResponse
// the dataResponse variable will only be defined within the Call back function
function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
// The Curly Brackets that follow mark the end of the callback handler method
});
// This log statement is not in the callback handler and there is no defined dataResponse variable which is probably why you got an error in the console
console.log(dataResponse);
You can fix this by moving the dataResponse log into the callback method, like this:
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
console.log(dataResponse);
});
There appear to be other problems with your code, in that you are trying to access $scope.apps before the data is returned; which will hinder your processing. Easiest approach would be to move that processing into the result handler:
// define $scope.columns outside of the result handler
$scope.columns = [];
// call to method in service
dataService.getData(function(dataResponse) {
$scope.apps = dataResponse;
alert(dataResponse);
console.log(dataResponse);
// inside the result handler; you run this code after $scope.apps is defined:
for(app = 0; app <= $scope.apps.length-1; app++) {
$scope.apps[app].thumb = ("000" + $scope.apps[app].app_id).slice(-3);
}
//separate apps to columns
var columns = [];
for (var i = 0; i < $scope.apps.length; i++ ) {
if (i % 3 == 0) columns.push([]);
columns[columns.length-1].push($scope.apps[i]);
}
$scope.columns = columns;
});
That's what promises and asynchronous calls are all about.
console.log(dataResponse);
console.log($scope.apps);
The first one won't work because dataResource is a private variable and not part of the same scope you're trying to print.
The second one won't work either because that get's populated at future time (after X seconds), after the $http request is finished so it will only be availableat that point.
One way to do something after the object is populated is to use
$scope.$watch("apps", function (){
// do stuff
});