Making Rest call within a rest call angularjs - javascript

I am trying to make a REST call to get the total count of the cities based on the text entered in a textbox.
I am making the same REST call the second time to get 25 records for the same search text.
For example if I entered the text Paris, the 1st rest call will take the maxPage size to 1000 and get me all the records.
And the second time, the maxPage is set to 25 to get the first 25 records.
The idea is to show the total number of records matching the search text and also show the 1st 25 records.
(for ex: 25/400)
The problem that I am facing is by the time I am done with entering the text, the 1st rest call is taking only a part of the text and the 2nd call is taking the whole text.
The count returned for the text is not matching the 2nd call's response.
For example: the 1st call is ending up with the text 'Par' and getting me 250 results where as the 2nd call is taking 'Paris'. I am ending up with 25/250 which is not correct.
May be this is because of some timing issue since the searchCities is called on ng-change. I cannot introduce a button on the screen so it has to be ng-change only.
Please help me resolve this.
Please have a look at the below code.
$scope.getCityCount = function(phrase){
var searchPhrase = phrase;
var dataObj = { term: searchPhrase, maxPage: 1000, pagefrom: 0 };
var srchdata = JSON.stringify( dataObj );
Cities.query( {}, srchdata, function(cityData) { //1st REST call
if (cityData.status == "success") {
$scope.cityCount= cityData.data.length; //total records
$scope.loadMoreCities(searchPhrase); //2nd call:to get 25 records
}
});
}
$scope.loadMoreCities = function(phrase){
var searchParam = { term: phrase, maxPage: 25, pagefrom: 0 };
Cities.query( {}, searchParam, function(dataObj) {
if (dataObj.status == "success") {
var citiesFound = dataObj.data;
}
});
}
$scope.searchCities = function( phrase ) {
if(phrase.length > 1){
$scope.getCityCount(phrase);
}
}
EDIT:
Though I am searching for Paris, I am getting final result for Pa. Please see the logs::
getSearchCount#1: {"searchTerm":"Paris","maxPage":10000,"pagefrom":0}is=====400
getSearchCount#2: {"searchTerm":"Paris","maxPage":25,"pagefrom":0}is===== 25
getSearchCount#1: {"searchTerm":"Pari","maxPage":10000,"pagefrom":0}is===== 105
getSearchCount#2: {"searchTerm":"Pari","maxPage":25,"pagefrom":0}is===== 25
getSearchCount#1: {"searchTerm":"Pa","maxPage":10000,"pagefrom":0}is===== 722
getSearchCount#2: {"searchTerm":"Pa","maxPage":25,"pagefrom":0}is===== 25
On the screen I get 25/722
HTML:
<input type="text" ng-model="phrase" ng-change="searchCities(phrase)">

This is a pretty bad idea. You should do server side paging instead. Have the API return the pager object along with the search results. For example, here is an API GET request:
/api/accounts?searchText=someText&pageSize=25&page=1
Here is the response:
{
"pager": {
"pageCount": 1,
"totalItemCount": 342,
"pageNumber": 1,
"pageSize": 25,
"hasPreviousPage": false,
"hasNextPage": true,
"isFirstPage": true,
"isLastPage": false,
"firstItemOnPage": 1,
"lastItemOnPage": 25
},
"results": [
{
"id": 15343,
"name": "Account Name",
},
// more accounts returned here...
{
"id": 2314,
"name": "Account Name 2",
}
],
"searchText": "someText"
}
When the client wants to load more, the request would change to this:
/api/accounts?searchText=someText&pageSize=25&page=2
..where you see we're trying to fetch the 2nd page.
How you implement server side paging is another question. Here is a rudimentary server side paging example to give you an idea.
Update:
If you absolutely can't change the api to deliver paging information, try using a debounce delay. You can read about it in the documentation but it will essentially trigger the ng-change update when the timer expires instead of on the keypress. Here is how you would implement it.
<input type="text" ng-model="phrase" ng-model-options='{ debounce: 1000 }' ng-change="searchCities(phrase)">

Related

AngularJS - httpget multiple times for same form

I am making an application. I have a form where the user can type in a product. I get the price with an angularjs service. I inject it in. RateInfoService.
So if I type in "Milk" it will say in the DOM {{rate}} -> $2
But if I fill in chips, it will change offcourse to {{rate}} -> $1.50
But what I want to fill in Milk and after that Chips.
So I want it to show in the html page
Milk->$2 & Chips->$1.50.
So it will show both items, the user can keep typing in products and submitting it. (ng-click). I might be able to do that in an array but note that I have a refresh rate. Not sure if that's possible to do with an ng-repeat or even if that is possible.
.controller("MainCtrl", function($scope, $http, $timeout, $ionicPlatform, $cordovaLocalNotification, $ionicPopup, RateInfoService, AlarmService, MonitorService) {
$scope.refreshRate = 5000;
$scope.refreshData = function() {
RateInfoService.getMarket($scope.alarmingMarket).success(function(data) {
$scope.rate = data.query.results.rate.Rate;
$scope.updateTime = data.query.results.rate.Time;
})
}
<label class="item item-input">
<span class="input-label">Product name</span>
<input type="text" min="3" ng-model="hard" name="text" autofocus required>
</label>
Also some extra info
$scope.submit = function() {
$scope.alarmingMarket = $scope.hard
console.log($scope.monitors);
};
$scope.alarmingMarket = $scope.hard
I used this so it would only get the market price after the user has filled in & pressed submit.
RateInfoService to get the price: http://pastebin.com/gHfhzMjR
I just found out it's possible to dump multiple objects in the url.
https://query.private%20in%20("Milk","Chips")&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=
How can I do this the best way in angular? i'm new in angularjs (3 weeks)
this is the Json formatted view (Explains the $scope.rate = data.query.results.rate.Rate;)
"results": {
"rate": [
{
"id": "MILK",
"Name": "MILK",
"Rate": "1.1054",
"Date": "10/26/2015",
"Time": "9:37pm",
"Ask": "1.1056",
"Bid": "1.1052"
},
{
"id": "CHIPS",
"Name": "CHIPS",
"Rate": "1.5349",
"Date": "10/26/2015",
"Time": "9:37pm",
"Ask": "1.5352",
"Bid": "1.5346"
I hope this was enough info.
*** Not sure why the styling goes wrong. Sorry for the messy page. Stack overflow gives a good preview of this post, but something goes wrong when I publish it. A lot of the code isn't greyed out
My solution
$scope.alarmingMarket = [];
$scope.submit = function() {
// $scope.alarmingMarket = $scope.hard
$scope.alarmingMarket.push($scope.hard);
console.log($scope.alarmingMarket);
};
This to push everything in the $scope.alarmingMarket array.
A service to get the rates
module.service('RateInfoService', function($http) {
return {
getMarket: function(alarmingMarket) {
var market = alarmingMarket
return $http.get('https://query.private%20in%20(%22'+ market + '%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=')
}
}
})
market is the array.
and to parse the Json
$scope.refreshData = function() {
RateInfoService.getMarket($scope.alarmingMarket).success(function(data) {
if($scope.alarmingMarket.length <= 1){ //if alarmingMarket[] has only 1 market
$scope.rate = [];
$scope.rate.marketid = data.query.results.rate.id;
$scope.rate.rate = data.query.results.rate.Rate;
$scope.rate.updateTime = data.query.results.rate.Time;
console.log($scope.rate);
}else{
angular.forEach(data.query.results.rate, function (value, key) {
$scope.rate = [];
$scope.rate.marketid = data.query.results.rate[key].id;
$scope.rate.rate = data.query.results.rate[key].Rate;
$scope.rate.updateTime = data.query.results.rate[key].Time;
console.log($scope.rate);
});
}
})
Sorry don't have enough rep to post a comment. Please give me a plus if this helps so I can get more rep.
From what you posted it seems like you are trying to repeat over items selected by the user and then getting each new rate per item (not sure if $scope.alarmingMarket is an array of items or not).
If you wanted to get all the latest rates for items selected by the user, you have to pass the entire array of items up and get back an array and let the ng-repeat do the work by assigning the value to the $scope.alarmingMarket (if that was your item list).

How to build a list of objects from JQuery selectors and send in Ajax post

1. Explanation of my screen and fields:
Considering each value on the screen as editable inputs with the names: name_{id of the row}
ordinary_1 = 4.5
ordinary_2 = 3.8
overtimeApproved = false
overtimeApproved = true
overtime15_1 = 0
overtime15_2 = 0
overtime20_1 = 0
overtime20_2 = 0
Table on the screen:
When I click on Approve button, I will need to build a json with the values when "Overtime Approved is checked", as below:
{
"Id": "2",
"Ordinary": "3.8",
"OvertimeApproved": "true",
"Overtime15": "0"
"Overtime20": "0"
}
To build this Json I need to select the fields using JQuery Selectors and then send the Json in an Ajax command to my MVC in order to update those fields.
I don't know how to use editable datatables, and the way I explained might be the quickest solution.
So I need:
Build that Json using JQuery Selector, each() command, etc.
Send that in an Ajax (This I know how to do)
var data = [];
$("#tableID tr").each(function() {
var cols = $(this).find("td");
data.push({
Id: cols.eq(0).prop('name').split('_')[1],
Ordinary: cols.eq(0).text(),
OvertimeApproved: cols.eq(1).find(":checkbox").is(":checked") ? "true" : "false",
Overtime15: cols.eq(2).text(),
Overtime20: cols.eq(3).text()
});
});

displaying an individual integer in webix

I want to display a single number (that would change, that's why I'm not hard coding it) from am object. This, however, doesn't display anything.
var game_data = {
amount: 1,
yes_left: 3,
nos_left: 1
};
var game_panel = {
view: "form", id:"game_panel",
rows:[
{cols:[
{
template:'<span class="main_title">Money: $#amount#.00 </span>',
data:{amount:game_data.amount},align:"center"
},
}
]
};
I've also tried returning it as a variable:
template: function(game_data) {return '<span class="main_title">Money: ' + game_data.amount + '.00 </span>'}
Any ideas how to get that to display?
The code that you are using is correct. You can check the the next working snippet http://webix.com/snippet/82566e82
If you plan to update this number dynamically, it will be better to use a bit different syntax
id:"t1",
template:'<span class="main_title">Money: $#amount#.00 </span>',
data: game_data, align:"center"
and for number updating, be sure to call template.refresh, as template doesn't track data changes automatically.
game_data.amount += 2;
$$("t1").refresh();
http://webix.com/snippet/e3b0450d

Twitter like "x new tweets" with .arte or .ajax?

I've found this great example to implement a twitter like "x new tweets" http://blog.hycus.com/2011/03/14/realtime-updates-like-twitter-using-phpmysqljquery/
In this example the .arte jQuery plug-in is used. However I think it can be done just as the same with .ajax and I've coded as:
$.ajax({
url:'async.php? main='+$('.boxOfMainPage:first').attr('id'),
success:function(results)
{
if(results!='')
{
if(results.indexOf('boxOfMainPage')>=0)
$('#tweetEveryone').prepend(results);
else
$('#newTweet').html("<center><a href=''>I found "+results+" new tweets</a></center>").show();
}
}
});
This checks the results and loads the result to tweetEveryone. Async.php simply makes a mysql_query and brings the new results. I've actually done exactly the same with the example however when I click the 'new tweet's like it sometimes causes a postback. In the example I haven't experience it. Can it be because of the difference between .arte and .ajax ?
It's nothing about the differences between arte and ajax (in fact and in a short way, arte is ajax that is called with an interval, trying to do something like "long polling")
So, u have a link without href value, this must "reload" ur page, ie, it will perform a GET request to the actual URL in window.location. A postback performs a POST request, this is really happening?
--- edited ---
If you wanna to do the same effect from twitter, it's simple.. In async.php, instead u write an link element that shows how many tweets has after the old state, make this page write a JSON object with all tweets, then, ur ajax function must get this JSON and convert it into a JS object. With this object, u'll be able to count how many updates u have to show and exactly which are they.
So, ur function could be like this (assuming that "#boxOfMainPage" is ur tweets container):
$.ajax({
url : 'async.php?main='+$('.boxOfMainPage:first').attr('id'),
success : function (tweets) {
window.NEW_TWEETS = tweets;
if ( NEW_TWEETS && NEW_TWEETS.length ) {
$('#newTweet').html("<center><a href='#' onclick='showNewTweets()'>I found "+NEW_TWEETS.length+" new tweets</a></center>").show();
}
}
});
The showNewTweets functions will be:
function showNewTweets() {
if ( window.NEW_TWEETS && NEW_TWEETS.length ) {
$('#newTweet').hide().html("");
for ( tweet in NEW_TWEETS ) {
$("#boxOfMainPage").prepend(buildTweetHTML(tweet));
}
}
}
And buildTweetHTML:
function buildTweetHTML(tweet) {
var $tweetElm = $("<div class='tweet'>");
$tweetElm.append("<h2>"+tweet.user+" said:</h2>");
$tweetElm.append("<p>"+tweet.content+"</p>");
$tweetElm.append("<p class='time'>"+tweet.time+"</p>");
return $tweetElm;
}
Finally, async.php should write JSON object like this:
[
{ user : 'Rafael', content : 'The content from tweet', time : 'X time ago' },
{ user : 'George', content : 'The content from tweet', time : 'Y time ago' }
{ user : 'Jack', content : 'The content from tweet', time : 'H time ago' }
]

Javascript Error,Escaping Problem,Grid not working,Error on Firebug

we are just started with Sigma Grid ,and it is awesome in its functionality when we compared to other Grids.
But i encountered some problem with Sigma Grid ,or may be with javascript.
I dont know whether the problem is with Grid or with my code.
I have a table with 3 fields namely MailID,MailName,MailData.
MailID is int ,MailName and MailData contains HTML content and it save as string in database.
When i load the Grid,i have some problems.
Problem 1 :
As i said above the Maildata contain html content,the following image is just a example with <*b> ,u can see that the HTML is automatically rendering on the grid itself ,i need the exact string.
please check the following image.
Problem 2 :
as u can see i have links on the grid,for edit,send,delete but on one filed its damaged.[check the image below ]
the code i used to render links is following .
{id: 'mailid' , header: "Action", width :120 , resizable : false, sortable : false , printable : false ,
renderer : function(value ,record,columnObj,grid,colNo,rowNo){
var no= record[columnObj.fieldIndex];
var cod = (record['maildata']);
return 'Edit | Delete';
Problem 3 :
The third value of MailData is 5 and it is integer ,when i alert the value its shows it correctly.
check the following image.
But when i alert the second value of maildata it giving error ,the second value of MailData is "hai newuser" ,it showing the following error on firebug.
missing ) after argument list
alert(hai newuser)
check the image below.
But when i alert 9th value of MailData it run correctly ,the content is <b>poy</b> ,this one is also save as string,but the grid automatically BOLD [which i dnt like].Check the image below.
also there are some others the 7the value contain ;".: etc ,also /b ,when i alert the data it showing the following error,
unexpected end of XML source
alert(<b>jjfdslkdjflsdnfsldfnf
dsOptions and ColOptions are following .
var dsOption= {
fields :[
{name : 'mailid' },
{name : 'mailname',type:"text" },
{name : 'maildata',type:"text" }
],
recordType : 'object',
}
function my_renderer(value ,record,columnObj,grid,colNo,rowNo)
{
var no= record[columnObj.fieldIndex];
return "<img src=\"./images/flag_" + no.toLowerCase() + ".gif\">";
}
function showalert(no)
{
$(document).ready(function()
{
$.post("http://localhost/power/index.php/power/give",{ name: no}, function(data)
{
//alert("Data Loaded: " + data);
$("#editor").show("fast");
$( '#txtar' ).ckeditor();
$('#txtar' ).val( data.maildata );
//$("#editor").html(data);
},"json"
);
});
}
var colsOption = [
{id: 'mailid' , header: "Mail ID" , width :60},
{id: 'mailname' , header: "Mail Name" , width :160 ,type:"text"},
{id: 'maildata' , header: "Mail Data" , width :190,type:"text" },
{header: "Group" , width :70,
editor : { type :"select" ,options : {'php':'php','asp':'asp'}
,defaultText : 'php' } },
{id: 'mailid' , header: "Action", width :120 , resizable : false, sortable : false , printable : false ,
renderer : function(value ,record,columnObj,grid,colNo,rowNo){
var no= record[columnObj.fieldIndex];
var cod = (record['maildata']);
return 'Edit | Delete';
} }
];
I am littlebit new in Javascript and Sigmagrid,i think that i am doing something worst with codes,pls help me to success.
Thank you.
Note : i posted the same Question on Sigma Grid Forum too,i think that it is not a problem.
Problem 2
The string cod contains a >
Problem 3
The string hai newuser needs to be contained in " or ' or it is considered a variable name
Basically you have to decide -- are you going to validate the html or not. If you don't validate the HTML then html errors in the data will show as errors on your page. You could also HTML escape the html so you will see the HTML codes -- this is probably the best plan.
Other sites use (like this one) use markdown -- this is easier to validate -- then they generate the actual HTML before display.
In addition you are having problems with the alert. Alert displays strings not HTML so you will see what you are seeing -- different results than expected depending on the HTML.
I would take a step back and ask yourself -- what is the type of the data, how am I going to display it. How am I going to validate that if it is HTML it is valid.
There are the problems you need to address -- your examples all stem from this problem.

Categories

Resources