Data Getting Repeated In DIV using Angular JS HTML - javascript

I am trying to create Just the way Facebook Post gets display. Here Conversation Message Contains the list of Post and on-click of the Post get-comments is getting Called which will fetch all the Comments as well as Reply corresponding to that Comment.
<div ng-repeat="coversationMessage in coversationMessageList">
<div ng-click="getComments(coversationMessage.channel_message_ID)">
<div>{{coversationMessage.date_time}}</div>
<div>{{coversationMessage.channel_message}}</div>
<div ng-if='commentList.length!=0'>
<div ng-repeat="comment in commentList">
<div>{{comment.date_time}}</div>
<div><b>{{comment.channel_message}}</b></div>
<div ng-if="commentMsg.replyCount> 0">
<div><a ng-click="showhideReply($index+1);$event.stopPropagation()">{{commentMsg.replyCount}}Replies</a></div>
<div class="mailText" ng-repeat="replyMessage in commentMsg.replyList">
<div>{{replyMessage.date_time |formatDateTime}}</div>
<div>{{replyMessage.channel_message}}</div>
</div>
</div>
</div>
</div>
</div>
Get Post Method will Populate the coversationMessageList (Array)
$scope.getPost = function(channel_thread_id) {
var promise = dashboardServices.getConversation(channel_thread_id);
promise.then(function(data) {
$scope.coversationMessageList = data.data;
}).catch(function(error) {
console.log("Error in fetching Conversation " + error);
});
}
Get Comments Will Populate commentList, replyCount and replyList
$scope.getComments = function(channel_thread_id) {
var promise = dashboardServices.getConversation(channel_thread_id);
promise.then(function(data) {
$scope.commentList = data.data;
console.log(JSON.stringify(data.data));
// This foreach method is to show comment reply for facebook
angular.forEach($scope.commentList, function(comment) {
if (comment.channel_message_ID) {
var channel_thread_id = comment.channel_message_ID;
var promise = dashboardServices.countReplyOnComment(channel_thread_id);
promise.then(function(data) {
$scope.commentMsg = {};
$scope.commentMsg = comment;
$scope.commentMsg.replyCount = {};
$scope.commentMsg.replyList = {};
$scope.countReply = data.data.length;
$scope.commentMsg.replyCount = $scope.countReply;
$scope.commentMsg.replyList = data.data;
comment = $scope.commentMsg;
console.log(comment);
}).catch(function(error) {
});
}
});
}).catch(function(error) {
});
}
The Problem is when i click on a Particular div the Comments and the reply is getting reflected to all the other div

Move the commentList into coversationMessage ...
Try the below code :
<div ng-repeat="coversationMessage in coversationMessageList">
<div ng-click="getComments(coversationMessage)">
<div>{{coversationMessage.date_time}}</div>
<div>{{coversationMessage.channel_message}}</div>
<div ng-if='coversationMessage.commentList && coversationMessage.commentList.length!=0'>
<div ng-repeat="comment in coversationMessage.commentList">
<div>{{comment.date_time}}</div>
<div><b>{{comment.channel_message}}</b></div>
<div ng-if="commentMsg.replyCount> 0">
<div><a ng-click="showhideReply($index+1);$event.stopPropagation()">{{commentMsg.replyCount}}Replies</a></div>
<div class="mailText" ng-repeat="replyMessage in commentMsg.replyList">
<div>{{replyMessage.date_time |formatDateTime}}</div>
<div>{{replyMessage.channel_message}}</div>
</div>
</div>
</div>
</div>
</div>
The service :
$scope.getComments = function (coversationMessage) {
var channel_thread_id = coversationMessage.channel_message_ID;
var promise = dashboardServices.getConversation(channel_thread_id);
promise.then(function (data) {
coversationMessage.commentList = data.data;
console.log(JSON.stringify(data.data));
// This foreach method is to show comment reply for facebook
angular.forEach(coversationMessage.commentList, function (comment) {
if (comment.channel_message_ID) {
var channel_thread_id = comment.channel_message_ID;
var promise = dashboardServices.countReplyOnComment(channel_thread_id);
promise.then(function (data) {
$scope.commentMsg = {};
$scope.commentMsg = comment;
$scope.commentMsg.replyCount = {};
$scope.commentMsg.replyList = {};
$scope.countReply = data.data.length;
$scope.commentMsg.replyCount = $scope.countReply;
$scope.commentMsg.replyList = data.data;
comment = $scope.commentMsg;
console.log(comment);
}).catch(function (error) {
});
}
});
}).catch(function (error) {
});
}

Related

How to filter a loop through local storage

I'm trying to add links to my navbar for searches that users have made, as well as if the user favorites the link. What I'm currently trying to achieve is that if, if the "past searched" section already contains the current search, don't add the current search to avoid duplicates. I am using localStorage to store this data with a stringified array (alreadySearched) and check if this array includes the current search; my problem is that the function always returns false. The same thing happens for the favorites dropdown. What am I doing wrong?
Here's my code:
// primary movie information (API #1)
var getMovie = function(title) {
$("#result").addClass("hidden")
$("#main").removeClass("hidden");
$("#search-form").trigger("reset");
//format the OMDB api url
var apiUrl = `http://www.omdbapi.com/?t=${title}&plot=full&apikey=836f8b0`
//make a request to the url
fetch(apiUrl)
.then(function(response) {
// request was successful
if (response.ok) {
response.json().then(function(movieData) {
// console.log(movieData)
var movieTitle = movieData.Title
getMovieId(movieTitle);
getSoundTrack(movieTitle);
getTrailer(movieTitle);
var movieObj = {
title: movieTitle,
}
var pastSearches = loadPastSearches();
var alreadySearched = false
if (pastSearches) {
pastSearches.forEach(s => {
if (s.title === movieTitle) {
alreadySearched = true;
}
})
}
if (!alreadySearched) {
for (var item of pastSearches) {
let searchEl = document.createElement("a")
let pastSearchTitle = item.title
$(searchEl).text(pastSearchTitle)
$(searchEl).addClass("past-search-item");
$("#past-search-dropdown").append(searchEl)
$(searchEl).click(function(e) {
e.preventDefault();
let title = pastSearchTitle
getMovie(title)
getQuotes(title)
});
}
}
saveSearch(movieObj)
showMovie(movieData);
});
} else {
alert("Error: title not found!");
}
})
.catch(function(error) {
alert("Unable to connect to CineXScore app");
console.log(error)
});
};
// save past search
var saveSearch = function(movieObj) {
var pastSearches = loadPastSearches();
pastSearches.push(movieObj);
localStorage.setItem("movieObjects", JSON.stringify(pastSearches))
}
loadPastSearches = function() {
var pastSearches = JSON.parse(localStorage.getItem("movieObjects"));
if (!pastSearches || !Array.isArray(pastSearches)) {
var pastSearches = []
}
return pastSearches;
}
// dropdown favorite soundtrack buttons
var saveTrack = function(trackObj) {
var faveTracks = JSON.parse(localStorage.getItem("trackObjects"));
if (!faveTracks || !Array.isArray(faveTracks)) {
var faveTracks = []
}
var alreadySearched = false
if (faveTracks) {
faveTracks.forEach(t => {
if (t.name === trackObj.name) {
alreadySearched = true;
}
})
}
if (!alreadySearched) {
let trackEl = document.createElement("a")
$(trackEl).addClass("fave-track");
$(trackEl).text(trackObj.name);
$(trackEl).attr("href", trackObj.url);
$(trackEl).attr("target", "_blank")
$("#favorite-tracks-dropdown").append(trackEl)
}
faveTracks.push(trackObj);
localStorage.setItem("trackObjects", JSON.stringify(faveTracks))
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Navigation Menu -->
<nav class="navbar navbar-default navbar-fixed-top">
<a id="logo" class="navbar-brand">CineXScore</a>
<div class="dropdown navbar-brand">Past Searches
<i class="fa fa-caret-down"></i>
<div id="past-search-dropdown" class="dropdown-content">
<a id="clear-searches">Clear</a>
</div>
</div>
<div class="dropdown navbar-brand">Favorite Tracks
<i class="fa fa-caret-down"></i>
<div id="favorite-tracks-dropdown" class="dropdown-content">
<a id="clear-favorites">Clear</a>
</div>
</div>
</nav>
This is a simple implementation that I think might help you.
async function fetchMovie(movieTitle) {
const apiUrl = `http://www.omdbapi.com/?t=${movieTitle}&plot=full&apikey=836f8b0`;
let res = await fetch(apiUrl);
res = await res.json();
const title = res.Title;
saveSearch(title); // Should only pass the string:title
}
fetchMovie('spiderman');
function saveSearch(title) {
if (!localStorage.getItem('movies')) localStorage.setItem('movies', ''); // Initialize the localStorage
// e.g: (In localStorage)
// Avenger,Spiderman,The Antman etc..
// return this string & convert into an array
let movies = localStorage
.getItem('movies')
.split(',')
.filter((n) => n);
// Check if the title is already exists
if (!movies.includes(title)) {
movies.push(title);
}
// Also store in localStorage as a string seperated by commas (,)
movies = movies.join(',');
localStorage.setItem('movies', movies);
}

Can't get field from Firebase Firestore

I've tried to retrieve a saved picture URL from Firebase Firestore, but I'm keep getting this error:
Uncaught (in promise) TypeError: Cannot read property 'picURL' of undefined.
I've tried a code, which you can see below. It's from "imgRef" and down.
HTML:
<div class="container">
<ul class="posts">
</ul>
</div>
JavaScript:
var postDocRef = db.collection('posts').doc(uid).collection('userPosts')
postDocRef.get().then(snapshot => {
setupPosts(snapshot.docs)
})
const posts = document.querySelector('.posts');
const setupPosts = (data) => {
let html = '';
data.forEach(doc => {
var docRefIDpost = docRef.id
const post = doc.data();
const li = `
<li>
<div class="title">${post.title}</div>
<div class="content">${post.content}</div>
<img class="img">
</li>
`;
var imgRef = db.collection('posts').doc(uid).collection('userPosts').doc(docRefIDpost);
imgRef.get().then(function(snapshot) {
const picURL = snapshot.data().picURL
if (picURL.exists) {
console.log(snapshot.data)
console.log(picURL)
var imgpost = document.querySelector(".img");
imgpost.src = picURL
}
})
html += li
})
posts.innerHTML = html;
}
});
The error is telling you that snapshot.data() returned undefined. As you can see from the API documentation, data() will return undefined when the requested document was not found. It's not clear here why, but your code should check for that first before accessing properties.
imgRef.get().then(function(snapshot) {
const data = snapshot.data()
if (data) {
const picURL = data.picURL
}
else {
// decide what you want to do if the document doesn't exist
}
})

AngularJS Why is my Controller not responsive?

This is a difficult question to ask, I will do my best to be brief:
I have a simple controller that I want to use to get information from an API and populate a selection list from trello.
Here is my controller:
function TrelloController($scope, $location, $routeParams, $timeout, dialogs, common){
var vm = this;
var controllerId = 'TrelloController';
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var logError = getLogFn(controllerId, 'error');
var scope = $scope;
var TRELLO = require("trello");
var key = '<my key>';
var token = '<my token>';
var trello = new TRELLO(key, token);
vm.title = "Trello Controller";
vm.addCard = addCard;
vm.getBoards = getBoards;
vm.toggle = toggle;
vm.getLists = getLists;
vm.getListsFromDictionary = getListsFromDictionary;
vm.isTrelloActive = false;
activate();
function activate(){
common.activateController([], controllerId)
.then(function () {
log('Activated Trello Controller');
initialise();
});
}
function initialise() {
vm.isTrelloActive = false;
getBoards();
getLists();
}
function toggle() {
vm.isTrelloActive = !vm.isTrelloActive;
log("TOGGLE CLICKED");
}
function addCard(cardName, cardDescription, listId) {
trello.addCard(cardName, cardDescription, listId, function (error, cardAdded) {
if (error) {
log("Could Not Add Card: ", error);
} else {
log("Card added: ", cardAdded.name);
}
});
}
function getBoards() {
trello.getBoards("me", function (error, boards) {
if (error) {
log("Could Not Get Boards: ", error);
} else {
log("found " + boards.length + " boards");
console.log(boards);
}
scope.boards = boards;
});
}
function getLists(){
for (var i=0; i<scope.boards.length; i++){
getListsWithBoardId(scope.boards[i].id, i);
}
}
function getListsWithBoardId(boardId, index){
trello.getListsOnBoard(boardId, function(error, lists){
if (error) {
log("Could Not Get Boards: ", error);
} else {
log("found " + lists.length + " lists on board:"+boardId);
console.log(lists);
}
scope.boards[index].lists = lists;
});
}
function getListsFromDictionary(boardId){
for (var i=0; i<scope.boards.length; i++) {
if(scope.boards[i].id == boardId){
return scope.boards[i].lists;
}
}
}
}module.exports = TrelloController;
This controller is intended to serve the purpose of governing my dialogue, simplified, this is that dialogue:
<div data-ng-controller="TrelloController as vm">
<div class="modal-header">
<img class="trelloLogo" name="trelloLogo" src="public/content/images/trello-mark-blue.png" alt="Add To Trello" ng-click="vm.toggle}">
<h3>{{parameter.heading}}</h3>
</div>
<div class="modal-body">
<form name="form">
<div ng-if="vm.isTrelloActive" class="form-group">
<label>Board</label>
<select name="typeInput" class="form-control" ng-required="true" ng-model="form.boardInput">
<option selected>Choose Board</option>
<option ng-repeat="board in scope.boards" value="{{board.id}}">{{board.name}}</option>
</select>
</div>
</form>
</div>
<!-- This section contains parts in the vm.addCard(...) that aren't included in this shortened version of The HTML template, I provided it with the additional fields for context of the API call at the end -->
<div ng-if="vm.isTrelloActive" class="modal-footer">
<button class="btn btn-primary" ng-disabled="!form.$dirty || !form.$valid" ng-click="vm.addCard(form.titleInput, form.descriptionInput, form.listInput)">Add To Board</button>
<button class="btn btn-default" ng-click="vm.isTrelloActive=false">Cancel</button>
</div>
</div>
When I am in the dialogue, Pressing the logo button appears to do nothing even though when it was previously set to: ng-click="vm.isTrelloActive = !vm.isTrelloActive" it would toggle the entire page. The activate method produces no logs and does not appear to run when pressed.
Why is this happening?

AngularJs - Execute Function in ng-repeat

My Web-App Should get images from server, show them and and give possibility to vote for Like it or Not.
Votes will be stored on DB.
my Controller :
$scope.beginSearch = function () {
$http
.get("http://example?q=" + $scope.search )
.then(function (response) {
$scope.url = response.data.data;
});
};
<tr ng-repeat="x in url">
<th>
<img src="{{x.images}}"></img>
<div class="well">
<i class="fa fa-thumbs-o-up fa-2x vertical-align" ng-click="vote_up(x.id)"></i>
<i class="fa fa-thumbs-o-down fa-2x vertical-align" ng-click="vote_down(x.id)" ></i>
</div>
</th>
</tr>
I was hoping to use a function in every ng-repeat, which would return
votes for like
{{ return_vote(x.id)}}
But it doesn't work, and as far I see, I should not use functions in html,
if they are not in ng-click functions.
ng-init also doesn't work.
Could anyone provide me help, how could I solve my problem?
Images are on some website, I just get them by using their WEB-API, so they doesn't have API for votes, I need to do it myself.
You can call your function inside brackets {{yourFunction(x.id)}} and add the logic to get the votes inside.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.url = [{
images: "http://lorempixel.com/g/100/100/",
id: 1
}, {
images: "http://lorempixel.com/100/100/",
id: 2
}]
$scope.getVotes = function(id){
//logic to get number of votes
return id * 5;
}
$scope.vote_up = function(id){
console.log("Vote up id " + id);
}
$scope.vote_down = function(id){
console.log("Vote down id " + id);
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="x in url">
<img src="{{x.images}}" />
<p>{{getVotes(x.id)}} votes</p>
<i class="fa fa-thumbs-o-up fa-2x vertical-align" ng-click="vote_up(x.id)"></i>
<i class="fa fa-thumbs-o-down fa-2x vertical-align" ng-click="vote_down(x.id)"></i>
</div>
</body>
Since you can't have the votes in the API you could alternatively create a service to get all the votes at once and then create some logic to match them to images.
e.g.
$scope.images = [];
var votes = [];
activate();
function activate() {
getImages().then(function () {
getVotes().then(function () {
matchVotesToImages();
//Now we have a property 'votes' in each image object which we can use in ng-repeat
});
});
}
function getVotes() {
var deferred = $q.defer();
$http.get('theUrl').then(success, fail);
function success(res) {
votes = res;
deferred.resolve();
}
function fail(res) {
console.log("Error");
console.log(res);
}
return deferred.promise;
}
function getImages() {
var deferred = $q.defer();
$http.get('theUrl').then(success, fail);
function success(res) {
$scope.images = res;
deferred.resolve();
}
function fail(res) {
console.log("Error");
console.log(res);
}
return deferred.promise;
}
function getIndex(array, property, valueToCompare) {
var i = 0;
var len = array.length;
for (i; i < len; i++) {
if (array[i][property] == valueToCompare) {
return i;
}
}
return -1;
}
function matchVotesToImages() {
var i = 0;
var len = $scope.images.length;
for (i; i < len; i++) {
//We pick need the votes of this specific image so
var indexAtVoteArray = getIndex(votes, 'id', $scope.images[i].id);
if (indexAtVoteArray != -1)
$scope.images.votes = votes[indexAtVoteArray];
else
$scope.images.votes = 0;
}
}
Thanks for answer.
$scope.vote_get = function (id) {
$http({
method: "GET",
url: "vote.php",
data: {
'id': id
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function (response) {
return response.data;
});
};
When I used this function to get votes, or return anything
, It does infinite loop.
Maybe I'am trying to do in wrong way, then please give me tips how to do that.
I'am just sure, that I need to send ID of image to .php file, this file will connect to database and return votes for provided ID.
Vote_up and Vote_down functions are same, they just POST data but seem to work ok.
Thanks
So, no one has idea :(?

append html to the div with AngularJS

How can i pass html through in AngularJS controller ?
Here is my list.html:
<div class="col-xs-3" ng-repeat="item in companyData">
<a ng-click="getPackageInfo({{item.iCompanyID}},'{{item.vCompanyName}}')" class="block panel padder-v bg-primary item">
<span class="text-white block">{{item.vCompanyName}}</span>
</a>
<div id="packagehtml"></div>
</div>
<div id="lp" class="col-md-12 listing-div hidden"></div>
in controller.js:
$scope.pData = [];
$scope.getPackageInfo = function(id,name) {
$scope.name = name;
var summery = SubscriptionoptioncompanylistFactory.getSummary(id);
document.getElementById("lp").classList.remove("hidden");
$('.packages-data').html('');
$('#loading').show();
SubscriptionoptioncompanylistFactory.getPackageInDetail(id).
success(function(data) {
if(data != 0) {
$("#lp").html(summery); // this is used to append the data
document.getElementById("np").classList.add("hidden");
Array.prototype.push.apply($scope.pData, data);
$('#loading').hide();
} else {
document.getElementById("lp").classList.add("hidden");
document.getElementById("np").classList.remove("hidden");
$('#loading').hide();
}
});
};
Here, I have wrote $("#lp").html(summery);, in that div I have to append html which comes from var summery = SubscriptionoptioncompanylistFactory.getSummary(id);. But this is not going to append the data. In console I can see that data comes in summary variable. How can I do?
have a look at below modifications
Use angular ng-show for showing/hiding elements
Use data binding and avoid Jquery like Dom manipulation
<div class="col-xs-3" ng-repeat="item in companyData">
<a ng-click="getPackageInfo({{item.iCompanyID}},'{{item.vCompanyName}}')" class="block panel padder-v bg-primary item">
<span class="text-white block">{{item.vCompanyName}}</span>
</a>
<div id="packagehtml"></div>
</div>
<div id="lp" ng-show="lbVisible" class="col-md-12 listing-div hidden">{{summaryBinding}}</div>
and the controller would look like :
$scope.pData = [];
$scope.getPackageInfo = function (id, name) {
$scope.name = name;
var summery = SubscriptionoptioncompanylistFactory.getSummary(id);
$scope.lbVisible = true; //document.getElementById("lp").classList.remove("hidden");
$('.packages-data').html('');
$scope.loadingVisible = true; //$('#loading').show();
SubscriptionoptioncompanylistFactory.getPackageInDetail(id).
success(function (data) {
if (data != 0) {
$scope.summaryBinding = summery; // $("#lp").html(summery); // this is used to append the data
$scope.npVisible = false; // document.getElementById("np").classList.add("hidden");
Array.prototype.push.apply($scope.pData, data);
$scope.loadingVisible = false; // $('#loading').hide();
} else {
$scope.lbVisible = false; //document.getElementById("lp").classList.add("hidden");
$scope.npVisible = false; //document.getElementById("np").classList.remove("hidden");
$scope.loadingVisible = false; // $('#loading').hide();
}
});
};
your snippet is not showing elements that you use :
np, #loading so just find them and add the `ng-show` with the proper scope variable : `npVisible , lbVisible , loadingVisible`
and note that we add the data using summaryBinding
hope this helps :)

Categories

Resources