how to get infinite scroll with remote data with angularjs - angularjs

Currently i am developing a listings portal here i am using angularjs as frontend and through this i am calling api to load data right now when a user hit all listings link whole data is loading and showing at this point the data is very less so problem but if data is large it will take some loading time, my requirement is when a user first click the link it has to show only top 50 listings and if user scrolls down the page then again api has to call for next 50 listings and so on how can i achieve this with angularjs.

Hope this helps.
$scope.limit=50;
$scope.loadMore1=true;
$scope.count=0;
$scope.loadMore=function()
{
$scope.limit=$scope.limit+100;
if($scope.limit>=$scope.count) {
$scope.loadMore1=false;
} else {
$scope.loadMore1=true;
}
$("html, body").animate({ scrollTop: $(document).height() }, 1000);
}
Inside your ajax call or api call
if(result.data.items.length<=50)
{
$scope.loadMore1=false;
} else {
$scope.count=result.data.items.length;
$scope.loadMore1=true;
}
And finally HTML list which loads certain number of results
<li ng-repeat="r in results | limitTo:limit"></li>
<button class="loadMore" ng-show="loadMore1" ng-click="loadMore()">Load more Items...</button>

Related

Track clicks on Elementor elements to Matomo

How to enable Matomo to track clicks on mailto links and tel links made with Elementor?
The Matomo script is added to Wordpress with the plugin "WP-Matomo Integration". The Matomo goals are listening to clicks to external websites with the pattern mailto:(.*) respectively tel:(.*). Isn't the Matomo client script supposed to fetch the goals from the tracking server and listen to these events? Is there another way to trigger those events?
I've created a script to search for elements with the class "matomogoal" and send the id of a goal to Matomo. It will push the goal id from the attribute matomogoalid to matomo, which you can get from your Matomo instance under Goals -> Manage Goals.
function trackClickGoal() {
var goalId = this.getAttribute("matomogoal");
_paq.push(['trackGoal', goalId]);
}
if (typeof _paq != "undefined") {
var elements = document.getElementsByClassName("matomogoal");
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', trackClickGoal, false);
}
} else { console.error('matomo client script is is not initialized'); }
<!-- HTML is supposed to look similar to this -->
<div class="matomogoal" matomogoal="goalid">
</div>
You can set those attributes by editing the link in Elementor. In the left Elementor panel click on "Advanced and set the "CSS Classes" field to matomogoal:
Then click on "Attributes" and set the value of "Custom Attributes" to matomogoal|goalid (while using the goal's ID you want to track with this click):
This also works with multiple goals on one page.

How to get different data in ng-repeat ? - AngularJS

I'm using AngularJS and I have created an web app.
I don't know how to get values from one specific link.
I have an admin page where I have all users and I get them using ng-repeat
<div ng-repeat="user in allusers">
But I have created routes for example user level and I have added them to http://mylink.com/user_level/john#doe.com -- (that's example so I will get user level via user email)
The recommended approach would be to have the service that retrieves the users, send the user's level in the user object itself.
But, if this is not an option and you have to make separate service calls to get the user's level, this is how you would do this.
function getUserLevels(users) {
for(var i=0; i<users.length; i++) {
getUserLevelForUser(users[i]);
}
}
function getUserLevelForUser(user) {
$http.get(BASE_URL + '/' + user.email)
.then(function (response) {
user.userLevel = response.data.userLevel;
});
}
getUserLevels($scope.users);
Since I do not have access to your API, I've created a plunker app that invokes the Open Movie Database API. In this demo, instead of the user's level, I will be fetching a movie's director. Also, instead of using the user's email in the url, I will be using the movie name.
See working plunker here

Implementing google custom search in angularjs

I am trying to implement google custom search in an angular js website.
When I click on the search button it does not display me anything, but the url is updated to the url.
I have followed the steps mentioned in the documentation by google.
I am not sure what I am doing wrong?
My search bar is located on the home page as -
<gcse:searchbox-only enableAutoComplete="true" resultsUrl="#/searchresult" lr="lang_en" queryParameterName="search"></gcse:searchbox-only>
my search result has -
<gcse:searchresults-only lr="lang_en"></gcse:searchresults-only>
Any input is much appreciated.
Thanks,
You may have more than one problem happening at the same time...
1. Query Parameter mismatch
Your searchresults-only does not match the queryParameterName specified on gcse:searchbox-only.
Index.html
<gcse:searchresults-only queryParameterName="search"></gcse:searchresults-only>
Search.html
<gcse:searchresults-only queryParameterName="search"></gcse:searchresults-only>
2. Angular.js is blocking the flow of Google CSE
Under normal circumstances, Google Search Element will trigger an HTTP GET with the search parameter. However, since you are dealing with a one-page application, you may not see the query parameter. If that suspicion is true when you target resultsUrl="#/searchresult", then you have two options:
Force a HTTP GET on resultsUrl="http://YOURWEBSITE/searchresult". You may have to match routes, or something along those lines in order to catch the REST request (Ember.js is really easy to do so, but I haven't done in Angular.js yet.)
Use JQuery alongside Angular.js to get the input from the user on Index.html and manually trigger a search on search.html. How would you do it? For the index.html you would do something like below and for the results you would implement something like I answered in another post.
Index.html
<div>GSC SEARCH BUTTON HOOK: <strong><div id="search_button_hook">NOT ACTIVATED.</div></strong></div>
<div>GSC SEARCH TEXT: <strong><div id="search_text_hook"></div></strong></div>
<gcse:search ></gcse:search>
Index.js
//Hook a callback into the rendered Google Search. From my understanding, this is possible because the outermost rendered div has id of "___gcse_0".
window.__gcse = {
callback: googleCSELoaded
};
//When it renders, their initial customized function cseLoaded() is triggered which adds more hooks. I added comments to what each one does:
function googleCSELoaded() {
$(".gsc-search-button").click(function() {
$("#search_button_hook").text('HOOK ACTIVATED');
});
$("#gsc-i-id1").keydown(function(e) {
if (e.which == 13) {
$("#enter_keyboard_hook").text('HOOK ACTIVATED');
}
else{
$("#search_text_hook").text($("#gsc-i-id1").val());
}
});
}
(function() {
var cx = '001386805071419863133:cb1vfab8b4y';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
I have a live version of the index.html code, but I don't make promises that will be permanently live since it is hosted in my NDSU FTP.

$scope not updating after passing to new view with $location.path

I have a simple CRUD I put together with Angularjs. From a product list display I pass the user to a new view template for the "Create New" form.
The form processes fine and updates the database. I then pass the user back to the list display using "$location.path(url)".
For some reason when the list page displays, the changes do not appear in the $scope and you have to refresh the page to see the changes.
Sample code:
$scope.acns = acnFactory.query()
.$promise.then(function (data) {
$scope.acns = data;
});
the above displays the list of items.
$scope.createAcn = function () {
$scope.acn.isActive = true;
acnFactory.create($scope.acn);
$location.path('/acn');
}
The above POSTs the new product then redirects to the list page (/acn)
My assumption is that the list page will reprocess or watch the changes to the $scope but the view does not update.
The problem is most probably here:
$scope.createAcn = function () {
$scope.acn.isActive = true;
acnFactory.create($scope.acn);
$location.path('/acn');
}
creating a product most certainly consists in sending an HTTP request to the server. This is asynchronous. This means that acnFactory.create() returns immediately after the request has been sent. Not after the response has been received.
So, this code sends the request to create the product and immediately goes to the page which lists the products. The GET request sent to get the product list is thus sent almost at the same instant as the one used to create the new product. The two requests are handled concurrently by the server, and the returned list contains the list without the new product, which is being created in a separate transaction.
You need to wait for the response to come back, and make sure it's successful, before going to the product list. Assuming the service returns a promise, as it should do:
$scope.createAcn = function () {
$scope.acn.isActive = true;
acnFactory.create($scope.acn).then(function() {
$location.path('/acn');
});
};

Angular js way to download file and show loading screen using the $resource

I am using Angular js to show loading screen. It works for all the REST services call except REST service to download the file. I understand why it is not working because for download I am not making any service call using $resource; instead of that I am using normal approach to download the file therefore Angular js code doesn't have any control on start/finish the service request. I tried to use $resource to hit this REST service however I am getting the data from this service and in this case loading screen was working fine however not sure how to use this data to display to user to download in angular way. Following are required details. Please help.
Approach 1 using iframe approach:
/*Download file */
scope.downloadFile = function (fileId) {
//Show loading screen. (Somehow it is not working)
scope.loadingProjectFiles=true;
var fileDownloadURL = "/api/files/" + fileId + "/download";
downloadURL(fileDownloadURL);
//Hide loading screen
scope.loadingProjectFiles=false;
};
var $idown; // Keep it outside of the function, so it's initialized once.
var downloadURL = function (url) {
if ($idown) {
$idown.attr('src', url);
} else {
$idown = $('<iframe>', { id: 'idown', src: url }).hide().appendTo('body');
}
};
Approach 2 using $resource (Not sure how to display data on screen to download)
/*Download file */
scope.downloadFile = function (fileId) {
//Show loading screen (Here loading screen works).
scope.loadingProjectFiles=true;
//File download object
var fileDownloadObj = new DownloadFile();
//Make server call to create new File
fileDownloadObj.$get({ fileid: fileid }, function (response) {
//Q? How to use the response data to display on UI as download popup
//Hide loading screen
scope.loadingProjectFiles=false;
});
};
This is the correct pattern with the $resource service:
scope.downloadFile = function (fileId) {
//Show loading screen (Here loading screen works).
scope.loadingProjectFiles=true;
var FileResource = $resource('/api/files/:idParam', {idParam:'#id'});
//Make server call to retrieve a file
var yourFile = FileResource.$get({ id: fileId }, function () {
//Now (inside this callback) the response data is loaded inside the yourFile variable
//I know it's an ugly pattern but that's what $resource is about...
DoSomethingWithYourFile(yourFile);
//Hide loading screen
scope.loadingProjectFiles=false;
});
};
I agree with you that this is a weird pattern and is different of other APIs where the downloaded data is assigned to a parameter in a callback function, hence your confusion.
Pay attention to the names and the cases of the parameters, and look that there're two mappings involved here, one between the caller to the $resource object and the object itself, and another between this object and the url that it contructs for downloading the actual data.
Here are some idea's for the second approach, you could present the user with a link after the download has happened:
With a "data url". Probably not a good idea for large files.
With a URL like "filesystem:mydownload.zip" You'd first have to save the file with the filesystem API. You can find some inspiration on html5rocks

Resources