Browser get freezed after loading huge data in angularjs (2k rows) - javascript

I am fetching data from server its loading time is quite good, But
while rendering all data almost 3k rows to view (angularJs) browser
get freeze and after some time its crashed also.
I tried pagination but after crossing 500 rows its start freezing. Some time its load all data into view but while scrolling or applying some event like click again got freeze.
Here is the code where i am listing all data.
<div class="divRow" ng-repeat="list in campaignDetailListfilterCopy.campaign_items | limitTo:totalDisplayed"">
<div class="divCell">
<div style="float:left;width: 325px;">
<div>
<span ng-if="list.monitor_type == 3">{{list.items.media_id}}</span>
<div class="moImgPreview hoverPreview creativePreview"> <img alt=""ng-src="{{list.items.media_thumbnail}}"/></div>
</span>
</div>
<p><strong class="lang" key="campaign_List_view_text2">Location</strong><span>{{list.items.media_address}}</span> </p>
</div>
</div>
<button class="btn" ng-click="loadMore()">Load more</button>
//the controller
$scope.totalDisplayed = 20;
$scope.loadMore = function () {
$scope.totalDisplayed += 20;
};
$scope.campaignDetailListfilterCopy.campaign_items = data;

you should keep two separate lists one holds all the data and the other one should hold only 20 at first and when you press load more it should add 20 more to the list from the list that has all the data with a loop
$scope.loadMore = function(){
let start = $scope.listToShow.length;
for(let i = start; i<= start + 20; i++){
if(angular.isDefined($scope.campaignDetailListfilterCopy.campaign_items[i]) {
$scope.listToShow.push($scope.campaignDetailListfilterCopy.campaign_items[i]);
}
}
}
$scope.listToShow= []
$scope.campaignDetailListfilterCopy.campaign_items = data;
$scope.loadMore();
And in your html
<div class="divRow" ng-repeat="list in listToShow">
and maybe inside your list you can add a button that calls the loadMore
<button ng-click="loadMore()"> load more</button>

Related

How to add html data to local storage and have it appear on a seperate html page

I have had trouble with a movie watch list project where i have two main pages (movie search page and watch list page) and one JS file they both share. I would like to be able to save a movie result after having searched for a movie on the first HTML page, and have it save to local storage and appear on the second HTML page.
I was able to create a watch list that lives on the same page as the movie search page and save selections temporarily, but when I refresh they disappeared. When I have tried saving to a separate page, I am unable to first fetch the ID where I want to insert the HTML data. I kind of understand this is because I am only able to load one page at at time, yet I have been unable to figure out what to do about it. I have also tried to use preventDefault to stop my second HTML page from refreshing in order to see if my data is saving, but i have been unsuccessful in this as well.
Here is my java script document which both pages share
function run(){
let ID
let movArr
document.querySelector("#search").addEventListener('click',async function(){
const movSearch = document.querySelector("#movieSearch").value
const res = await fetch(`https://www.omdbapi.com/?s=${movSearch}&type=Movie&apikey=3c746e2`)
const data = await res.json()
movArr = data.Search
html=""
for(let movie of movArr)
{
const rez = await fetch(`https://www.omdbapi.com/?i=${movie.imdbID}&type=Movie&apikey=3c746e2`)
const datatwo = await rez.json()
ID = datatwo.imdbID
html +=
` <div class="movieInput" style="display:flex;align-items:center">
<div>
<img src="${movie.Poster}" style="width:99px;margin:42px 0 0 44px">
</div>
<div></div>
<div style="margin:3px 0 0 21px">
<text style="font-weight:bold; font-size:18px">${movie.Title}</text>
<p>${datatwo.imdbRating}</p>
<div style="display:flex; gap:36px; font-size:12px">
<p>${datatwo.Runtime}</p> <p>${datatwo.Genre}</p> <p><i class="fa-solid fa-circle-plus" data-add="${datatwo.imdbID}"></i></p>
</div>
<div style="margin:-20px 0 0 0">
<p>${datatwo.Plot}</p>
</div>
</div>
</div>
<hr />`}
document.querySelector("#movies").innerHTML = html
}) }
function watchlist(){
localStorage.setItem( 'film' , JSON.stringify(html) )
document.querySelector('#moviesToo').innerHTML = JSON.parse(localStorage.getItem('film'))
}
function watch(){
let html
document.addEventListener('click', async function(e){
if(e.target.dataset.add){
console.log('clicked!')
const movie = e.target.dataset.add
const dez = await fetch(`https://www.omdbapi.com/?i=${movie}&type=Movie&apikey=3c746e2`)
const datathree = await dez.json()
ID = datathree.imdbID
html =
`
<div class="movieInput" style="display:flex;align-items:center">
<div>
<img src="${datathree.Poster}" style="width:99px;margin:42px 0 0 44px">
</div>
<div></div>
<div style="margin:3px 0 0 21px">
<text style="font-weight:bold; font-size:18px">${datathree.Title}</text>
<p>${datathree.imdbRating}</p>
<div style="display:flex; gap:36px; font-size:12px">
<p>${datathree.Runtime}</p> <p>${datathree.Genre}</p> <p><i class="fa-solid fa-circle-minus" data-add="${datathree.imdbID}"></i></p>
</div>
<div style="margin:-20px 0 0 0">
<p>${datathree.Plot}</p>
</div>
</div>
</div>
<hr />`}
return watchlist()
})
}
run()
watch()

How to use localStorage value filter in ng-repeat

I've set a value when the user click vote choice. Its working.
.then(function(response) {
localStorage.setItem('isClicked', 'Yes');
var i = +localStorage.key("nid");
var nidId = 'nid' + localStorage.length;
localStorage.setItem(nidId, vm.nid);
vm.clickedBefore = true;
})
This is my HTML scope:
<div class="card myfunc" ng-repeat="myfunc in myfuncPage.myfuncs" id="{{myfunc.nid}}" >
<div class="item item-text-wrap">
<h2 class="item-icon-left"><i class="icon ion-ios-analytics"></i>
{{myfunc.title}}</h2>
</div>
<div class="item item-text-wrap" ng-show="localstorage">
<img ng-src="{{myfunc.field_image.und[0].imgPath}}"/>
<p class="custom-class" ng-bind-html='myfunc.body.und[0].value'>
</p>
<ul ng-repeat="vote in myfunc.advmyfunc_choice">
<li ng-repeat="voteselect in vote">
<div class="row">
<button class="col button button-outline button-dark" ng-click="myfuncPage.sendNid(myfunc);myfuncPage.sendVote(voteselect);showVoted = ! showVoted" >{{voteselect.choice}}</button>
<div class="voted-screen" ng-show="showVoted">
<h3>Thanks.</h3>
</div>
</div>
</li>
</ul>
</div>
</div>
In basically, I need remember the div via localStorage and when the page refresh, hide choice divs.
ng-show="showVoted" working on click but I need on refresh.
What is the best way to do it? Thanks.
I am not sure what local storage module you are using, so I can't be specific, but I would write factory that handles the retrieval and storage of the values you need
(function () {
var voteFactory = function (localStorage) {
return {
getVote: function (key) {
var isVoted = false;
// get local storage item, set voted etc
var voted = localStorage.getItem(key);
if(voted) {
isVoted = voted;
}
return isVoted;
},
setVote: function(key, value) {
localStorage.setItem(key,value);
}
};
};
app.factory('voteFactory', ['localStorage', voteFactory]);
})();
Then within the scope controller/directive you are using to show or hide you would have a function:
$scope.showVoted = function(key) {
return voteFactory.getVote(key);
}
then ng-show="showVoted(theidentifieryouwantouse)"
It is also worthwhile to mention I would use ng-if instead of ng-show. To be more efficient you could store your votes as an array instead of individual values and do a check to see if you have retrieved all values, get from local storage if not. Then your functions would interrogate retrieved array instead of repeated calls to local storage. I would also advice maybe using a promise in the factory because retrieval from local storage could be delayed causing some ui oddities.
Hopefully this is along the lines of what you are looking for. I can elaborate if needed.

Update html meteor?

I am trying to output an estimated time based off the number of items (people) within my database (this is a wait list). Currently I save a value in the quick form called countNumber. This is just set to 1 everytime. I then get the count of all the items by finding the all items that have countNumber = 1 (all of them). I then try updating the html using getElementById().
The problem I am having is that when I add a person to the database the estimated time will go up appropriately. However when I refresh the page the html resets to 0 like the initial html that is put in.
How do I fix this so that the html will always display the appropriate time even when the page is refreshed?
Html code:
<head>
<title>Wait List</title>
</head>
<template name= "home">
<body>
<h2 id="insert">Approximate Wait Time: 0 Minutes</h2>
<div class="col-lg-6 col-lg-offset-3">
{{>quickForm id="studentForm" collection="Students" type="insert" template="bootstrap3-horizontal" label-class="col-sm-3" input-col-class="col-sm-9"}}
</div>
</body>
</template>
js code:
AutoForm.hooks({
studentForm:
{
onSuccess: function (insert,result) {
var totalCount = Students.find({countNumber:1}).count();
var waitTime = "Approximate Wait Time: " + totalCount*15 +" Minutes";
document.getElementById("insert").innerHTML = waitTime;
...
},
}
});
You should put this into a helper instead of a hook.
Template.home.helpers({
waitTime: function(){
var totalCount = Students.find({countNumber:1}).count();
var waitTime = totalCount*15;
return waitTime;
}
});
and change the <h2> line in the html to this.
<h2 id="insert">Approximate Wait Time: {{waitTIme}} Minutes</h2>

ng-repeat appending data multiple times

HTML
<div ng-app="templeApp" ng-controller="templeList">
<div ng-repeat="temple in temples track by $index" >
<h2>{{temple.strTempleName}}</h2>
<h4>{{temple.strTempleDescription}}</h4>
<h4>5km from current location</h4>
</div>
</div>
JS
var templeApp = angular.module('templeApp', [])
.controller('templeList',function($scope,$http){
$scope.temples = [{"_id":"new","strTempleName":"Temple 1 Name","strTempleDescription":"Temple 1 description","strContactNumber":"+91899999999","strTempleLocation":"Chennai","iTempleRating":5,"strContactPersonName":"","strTempleCoordinates":""}] ;
$http.get("https://gist.githubusercontent.com/vigneshvdm/d106ea482a792c60dff8/raw/c8f020eb54c4068e40884b8d84c972d92e8e4e08/vicky%20test%20file").success(function(data){
$scope.temples = data[0]; //uncomment this line to see error
console.log(data[0]);
});
});
PROBLEM
When i comment the $scope.temples = data[0]; line, ne-repeat is appending data only once, but when i assign the data to $scope.temples its appending same data multiple time
DEMO LINK
remove track by $index in ng-repeat and change the below like this
in this example i used temple.strTempleName for track by filter make sure it is return unique names.
<div ng-app="templeApp" ng-controller="templeList">
<div ng-repeat="temple in temples track by temple.strTempleName" >
<h2>{{temple.strTempleName}}</h2>
<h4>{{temple.strTempleDescription}}</h4>
<h4>5km from current location</h4>
</div>
</div>

too much recursion when inserting data in mongodb - meteor

I have a couple of templates with some copy in them. The copy is editable by the user and when the user edits and saves (by clicking a button) I insert the edited copy along with all HTML tags (for later, when I print the data out again) in a db.
When I log the data it works but as soon as I try and write it to the db I get a 'too much recursion' error and I don't understand why.
// Event
Template.editControls.events({
'click .save': function(e) {
var target = e.currentTarget.parentNode;
var targetContent = target.nextElementSibling;
if(targetContent.isContentEditable) {
var targetData = targetContent;
var selectedCopy = Session.get('activeElement');
ContentCollection.update(selectedCopy, {$set: {content: targetData}});
targetContent.contentEditable = false;
}
}
});
// Template
<section class="content" id="header">
<ul class="inline-list">
<li class="edit">edit</li>
<li class="save">save</li>
</ul>
<div class="content__editable" contenteditable="false">
<p>Header content I can change</p>
</div>
</section>

Categories

Resources