Im using AngularJS on front-end and PHP on back-end that is hosted in Google App Engine. Now when i try to fetch JSONP data directly from server it goes fast, when i use a Google service the time increases with almost 1s. Very short: Im getting my data very slow, it takes 1.3-1.8s to render data on screen.
This is my Client-code-Controller:
angular
.module('RDash')
.controller('tables-ctrl5', ['$scope','$http', function($scope,$http) {
$http({
method: 'jsonp',
url: 'https://gtmdocx.appspot.com/test5?callback=JSON_CALLBACK',
headers: {"Content-Type":"application/json"}
}).then(function ListCtrlresponses(response) {
$scope.GTMWorkspacesTags = response.data.tag;
console.log(response.data.tag);
$scope.GTMWorkspacesTagsLength = response.data.tag.length;
}, function Error(response) {
$scope.users = response.statusText;
});
}])
im using ng-repeat:
<div class="col-lg-6">
<rd-widget>
<rd-widget-header icon="fa-tasks" title="Google Tag Manager - URL: http://gtmdocx.appspot.com/test3 (LISTE AV TAGS I WORKSPACE) = Hent ut PATH fra LISTE av Workspace (EX: accounts/1746756959/containers/7454209/workspaces/8)">
</rd-widget-header>
<rd-widget-body classes="medium no-padding">
<div class="table-responsive">
<table class="table table-striped" ng-controller="tables-ctrl5">
<thead>
<tr>
<th>AccountID</th>
<th>ContainerID</th>
<th>TagName</th>
<th>Path</th>
<th>test</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="workspace in GTMWorkspacesTags">
<td>{{ workspace.accountId }}</td>
<td>{{ workspace.containerId }}</td>
<td>{{ workspace.name }}</td>
<td>{{ workspace.path }}</td>
<td>{{GTMWorkspacesTagstest}}</td>
</tr>
</tbody>
</table>
</div>
</rd-widget-body>
<rd-widget-footer>
Footer
</rd-widget-footer>
</rd-widget>
</div>
Now this is my PHP-code: very simple and straight forward: (PS: using slim)
// 4) Gets all TAGS related to this WORKSPACE
$app->get('/test5', function (Request $request, Response $response) {
$client = new Google_Client();
$client->setApplicationName("gtmdocx");
$client->setAuthConfig('service_account.json');
$client->setScopes(['https://www.googleapis.com/auth/tagmanager.readonly',
'https://www.googleapis.com/auth/tagmanager.manage.accounts',
'https://www.googleapis.com/auth/tagmanager.edit.containers',
'https://www.googleapis.com/auth/tagmanager.publish'
]);
$service = new Google_Service_TagManager($client);
$containers = $service->accounts_containers_workspaces_tags->listAccountsContainersWorkspacesTags('accounts/1746756959/containers/7454209/workspaces/8');
echo $_GET['callback'] . '('.json_encode($containers).')';
});
If you look at the timing on response:
I hope someone has experienced this before. This is really bothering me that it is using so much time to render. When i type in directly the URL in browser i get response right away, but in angularjs as front its slow. Im using JSONP to fetch because of CORS, can this be the problem?
Related
I have got code that reads the data from the array perfectly when I use a AJAX request. When I push an object to the array however, ng-repeat doesn't render the new row and I have to refresh the page to then fetch the data that was sent to server.
Why does it do this?
Thanks
Javascript
function processError() {
var responseCode = 404;
var error = {};
error["client"] = document.getElementById('client').value;
error["errorMessage"] = document.getElementById('error-message').value;
error["simpleRes"] = document.getElementById('simple-fix').value;
error["fullRes"] = document.getElementById('full-fix').value;
error["reason"] = document.getElementById('reason').value;
var errorJson = JSON.stringify(error);
$.ajax({
url: "../ErrorChecker/rest/error",
type: "POST",
data: errorJson,
contentType: "application/json"
})
.done(function (data, statusText, xhr, displayMessage) {
$('.form').hide();
responseCode = xhr.status;
reloadData(data);
});
function reloadData(data) {
if (responseCode == 200) {
processPositiveResponse(data);
} else {
$('#negative-message').show(1000);
}
}
}
function processPositiveResponse(data) {
$('#positive-message').show(1000);
updateTable(data);
$('#errorTable').DataTable().destroy();
setupTable();
clearInputs();
console.log($scope.controller.errors);
}
function updateTable(data) {
$scope.controller.errors.push({
"id": data,
"client": document.getElementById('client').value,
"errorMessage": document.getElementById('error-message').value,
"simpleRes": document.getElementById('simple-fix').value,
"fullRes": document.getElementById('full-fix').value,
"reason": document.getElementById('reason').value
})
}
HTML
<tbody>
<tr ng-repeat="x in dataCtrl.errors">
<td class="collapsing">
<div class="ui toggle checkbox">
<input type="checkbox">
<label></label>
</div>
</td>
<td style="display: none">{{ x.id }}</td>
<td>{{ x.client }}</td>
<td>{{ x.errorMessage }}</td>
<td>{{ x.simpleRes }}</td>
<td>{{ x.fullRes }}</td>
<td>{{ x.reason }}</td>
</tr>
</tbody>
That's because you're using jQuery and Angular together. Don't do that. EVER. Angular is not aware of what jQuery is doing, and jQuery is not aware of what Angular is generating in the DOM. Solution : REMOVE jQuery and use Angular's own $http service.
The same way, don't use document.getElementById('full-fix').value. You're taking Angular backwards. Angular generates the DOM from data, so you don't need to select DOM elements to read their value because that value is already in your data.
Update the document. Use scope apply as a quick fix. Not the way to do it imo. But it will solve your problem fast. On my mobile if I do not forget ill update this comment later with more details and best practises. For now a google search to scope apply will help you a long way.
I am developing my first angular-app with an .Net backend.
I get my data async from a webmethod using a http.post. That all works fine.
Client-side I would like to do some simple calculations (a final row in a table which contains sums of all the data in table)
The code to do this is pretty straight forward but my problem is the data i not ready when I try to do it.
I have read that I could use a promise and a service or a factory. But I am not sure what we be the best way to go.
My code for the view:
<div ng-controller="taskCtrl as ctrl">
<div class="col-md-10 container outer">
<h1 class="center-block">{{ctrl.SprintViewModel.SprintName}}</h1>
<table id="SprintMetaDate">
<tr><td>Projekt:</td><td>{{ctrl.SprintViewModel.ProjektName}}</td></tr>
<tr><td>Periode:</td><td>{{ctrl.SprintViewModel.StartDate}} - {{Ctrl.SprintViewModel.EndDate}}</td></tr>
<tr><td>Udarbejdet af/d:</td><td>{{ctrl.SprintViewModel.MadeBy}}</td></tr>
</table>
<h3>Sprint Resume:</h3>
<br/>
{{ctrl.SprintViewModel.SprintResume}}
<h3>Sprint afslutning:</h3>
{{ctrl.SprintViewModel.SprintDemo}}
<h2>Scope og Økonomi </h2>
<h3>Sprint Opgaver</h3>
<table id="SprintTasks" class="col-md-12">
<tr><th>Opgave</th><th>Estimat</th><th>Forbrug</th><th>Udest.</th><th>*</th><th>Pris (DKK)</th></tr>
<tr ng-repeat="x in ctrl.SprintViewModel.Tasks">
<td style="width: 40%">{{ x.Description }}</td>
<td>{{ x.TimeEst }}</td>
<td>{{ x.TimeUsed }}</td>
<td>{{ x.TimeRemaining }}</td>
<td>{{ ctrl.CalcPrecisionOfEstimat(x.TimeUsed,x.TimeRemaining,x.TimeEst) | number:2}} %</td>
<td>{{x.Price}}</td>
</tr>
<tr>
<td>Ialt</td>
<td>{{ ctrl.TotalEstimat() }}</td>
<td>{{ ctrl.TotalTimeUsed() }}</td>
<td>{{ctrl.TotalTimeRemaining()}}</td>
<td>{{ctrl.TotalPrecision()}}</td>
<td>{{ctrl.TotalPrice()}}</td>
</tr>
</table>
* Forbrug + Udestående i forhold til estimat
<br/>
Udestående opgaver er planlagt ind i næstkommende sprint.
</div>
</div>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('taskCtrl', function($scope, $http) {
var ctrl = this;
ctrl.SprintViewModel = null;
ctrl.TotalEstimat=function() {
var totalEstimat=0;
for (i=0; i<ctrl.SprintViewModel.Tasks.count;i++) {
totalEstimat += ctrl.SprintViewModel.Tasks[i].Estimate;
}
return totalEstimat;
}
ctrl.TotalPrecision = function () {
var totalPrecision=0;
angular.forEach(ctrl.SprintViewModel.Tasks, function (value, key) {
totalPrecision += Number(value);
});
$http.post('SprintRapport.aspx/GetSprintViewModel', {})
.then(function(response, status, headers, config) {
console.log("I success");
ctrl.SprintViewModel = response.data.d;
});
});`
As already mentioned I get a nullreference every when the page-load on all the methods in the last row, because ctrl.SprintviewModel is undefined. I have only included one of the methods for simplicity, the problem is the same for all of them.
So my question is how do I make sure that ctrl.TotalEstimat() first get called then ctrl.SprintViewModel is assigned?
You can add ng-if condition to the last <tr> which resolves to true when data is ready to populate in your controller. So you can define $scope.loading = false initially and once your code is ready to populate you set $scope.loading=true and that will call $digest cycle internally and your view gets updated.
There are several things that you could do. I've fixed this kind of issue by placing guard conditions in the functions. These check that the necessary variables have been set before continuing. So adding if (!ctrl.SprintViewModel) return; at the beginning of the function as follows:
ctrl.TotalEstimat=function() {
// Guard Condition to prevent function executing in invalid state.
if (!ctrl.SprintViewModel) return;
var totalEstimat=0;
for (i=0; i<ctrl.SprintViewModel.Tasks.count;i++) {
totalEstimat += ctrl.SprintViewModel.Tasks[i].Estimate;
}
return totalEstimat;
}
It's another option, but as you have already alluded to, I think that promises and the $q library is the proper angular way to fix this sort of thing.
I am trying to build an angular app that searches a Github user based on their username and displays the list of their repos.
Next when the user clicks on any repo name it should display the list of open issues and contributors.
here's the plunk http://plnkr.co/edit/6ZzIkB7W1HgxQtuQjo5k?p=preview
please visit the plunk and make a test run on the app, i'm not able to explain my issue properly
my repocontroller js.
(function(){
var app = angular.module('plunker');
app.controller('RepoCtrl', function($scope, $routeParams, $http, $log){
var username = $routeParams.username;
var reponame = $routeParams.reponame;
var onSuccess = function(response){
$scope.repo = response.data;
$http.get($scope.repo.contributors_url)
.then(onCollab , onError);
};
var onCollab = function(response){
$scope.contributors = response.data;
};
var onError = function(reason){
$scope.error = "Data Load Error";
};
//GET https://api.github.com/repos/:owner/:repo/contributors
$http.get('https://api.github.com/repos/' + 'username/' + 'reponame')
.then(onSuccess, onError);
});
}());
I'm encountering a trouble in the last stage i.e when the user clicks on any repo name instead of loading repo.html page , the application reloads the main page again.
Can you help me out please ? :)
Since your site's default url is like http://localhost/#!/main
You have to chenge your links with #!/ like in user.html
{{repo.name}}
and in repo.html
Back To Main
Back To {{repo.owner.login}}
Just remove # from anchor link which is in ng-repeat="repo in repos | orderBy:repoSort" show below code for more info
<div>
<h2>{{error}}</h2>
<h1>{{user.name}}</h1>
<a href="{{user.blog}}" target=_blank>{{user.blog}}</a>
<h1>{{user.email}}</h1>
<h1>{{user.location}}</h1>
<img ng-src="{{user.avatar_url}}" title={{user.name}} width="250px" id="userDetails"> OrderBy:
<select ng-model="repoSort">
<option value="-stargazers_count">Stars</option>
<option value="name">Name (A-Z)</option>
<option value="-name">Name (Z-A)</option>
</select>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Stars</th>
<th>Language</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="repo in repos | orderBy:repoSort">
<td>
{{repo.name}}
</td>
<td>{{repo.stargazers_count | number}}</td>
<td>{{repo.language}}</td>
</tr>
</tbody>
</table>
<a href='#/main'>Back To Main</a>
I am building an application using ASP.NET and AngularJs. I am trying to pass object id from the view (HTML) to the Angular controller, to then make an http call to the api. I don't know how to pass the id of an specific object from this table when the delete link is clicked.
<table class="table table-responsive table-striped">
<tr ng-repeat="post in viewModel.posts">
<td>{{ post.text }}</td>
<td>{{ post.postedOn | date:'medium' }}</td>
<td>Edit</td>
<td><a ng-click="viewModel.deletePost" class="btn btn-sm">Delete</a></td>
</tr>
</table>
and this is how I am trying to make the call to the API from the controller
// delete post function
viewModel.deletePost = function () {
viewModel.errorMessage = "";
$http.delete("http://localhost:61878/api/posts", viewModel.newPost.id)
.then(function (response) {
// sucess delete
viewModel.posts.delete(response.data);
viewModel.newPost = {};
}, function () {
// failed to delete
viewModel.errorMessage = "Failed to delete post"
})
.finally(function () {
});
};
Does anybody know how can I pass the id of the respective post on the row clicked to the Angular controller?
viewModel.deletePost is a function - just call it with parameters.
<a ng-click="viewModel.deletePost(post.id)" class="btn btn-sm">Delete</a>
After that you just have to add the parameter to the function:
viewModel.deletePost = function (id) { ... }
I have an HTML file which displays a data set in firebase as a table. As the data is in firebase I am using (key,client) in clientInfo to get the key as well. This key is used for the purpose of deleting a row.
<table class="meeting">
<tr ng-repeat="(key, client) in clientInfo">
<td>{{ client.name }}</td>
<td>{{ client.discount }}</td>
<td>{{ client.vms }}</td>
<td><button class="btn btn-delete tooltip" ng-click="deleteClient(key)">
<span>Delete this client</span></button>
</td>
</tr>
</table>
But while clicking the button, the deleteClient(key) function is not called. Is it because the information of key isnt available on a Cell(td) level and is available only on a Row(tr) level in the HTML?
I am using an older version of Firebase where $as.Object() is required to store data as an Object.
My controller in Angular
myApp.controller('DataController', function ($scope, $rootScope, $firebase, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL + '/clientInfo');
var clientInfo = $firebase(ref);
$scope.clientInfo = clientInfo.$asObject();
$scope.deleteClient = function(key) {
clientInfo.$remove(key);
};
Is it possible to do this in Table format? If so, what am I doing wrong? Please help me solve this issue