AngularJS app freezes during query - angularjs

I am running an Angular app with a Parse backend. When I make a query, the app freezes, even when the DOM doesn't depend on the data being grabbing at the time. That is why this answer was not so helpful. Is there any way to have the rest of the app run along while some request is in progress?
Below is the code that freezes everything until the request resolves. The Parse Javascript SDK comes with promises, which is what 'QS.errorQuery.find()` returns.
function get() {
var queries = [
QS.errorQuery.find(),
QS.resLogQuery.find()
];
return $q.all(queries)
.then(function(res) {
return {
errors: res[0],
logs: res[1]
}; //end return
}); //end return
}; //end get
get().then(function(res) {
$scope.lineData = DP.bigLineParser(res.errors, res.logs);
});

The request is async so as the response is coming in, your UI wont freeze up. The long delay is probably happening when Parse gets its response from the server and parses it.

Related

React Remote Console Logging

I setup an Express Server with Mongo to record console logs during debug testing of an Electron app using React.
I simply use ajax to send what I would normally print with console.log. This works fine with individual events I want logged, but how do I export the entire chrome style console as an object so that anything that would reach the console (example: webpack messages, messages from other components etc) would all be accessible as one object that I can do a POST on.
Basically a way to record everything that you would see in the console whether it was from a 3rd party package or that I expressly logged myself. Is there a console dump all method of some sort I'm not seeing in the chromium/electron/react docs?
example:
//import some debugger method to POST to server collecting logs
export function debugpost(logobject) {
$.ajax({
type: "POST",
url: "http://" + "192.168.0.94" + ":3000/tasks",
headers: {
},
data: {
log: logobject
},
success: function(data) {
}.bind(this),
error: function(errMsg) {
console.log(errMsg);
}.bind(this)
});
}
//simple way of recording logs in other component.
var testlogmessage = "This isn't right"
debugpost(testlogmessage);
Logging individual events to the server is easy. How do I dump the entire console?
UPDATE
Mentioned below was to tie into the process stdout and stderr. I tried the recommended package capture-console and also this code snippet:
var logs = [],
hook_stream = function(_stream, fn) {
// Reference default write method
var old_write = _stream.write;
// _stream now write with our shiny function
_stream.write = fn;
return function() {
// reset to the default write method
_stream.write = old_write;
};
},
// hook up standard output
unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
logs.push(string);
});
However both give me this error with write when using with react:
TypeError: Cannot read property 'write' of undefined
hook_stream
That particular method seems to log the electron node side fine when I use it in the electron main.js. However I can't get it to work within my react components.
One way of doing this is to overwrite the console.log with your custom implementation, so whenever any part of the code calls the console.log the call will be intercepted by your custom function where you can log the message to your remote server using some API calls.
Once you have logged your message you can call the original console.log method.
Following example shows a custom implementation of console.log method.
var orgLog = console.log;
console.log = function(message) {
alert("Intercepted -> " + message); //Call Remote API to log the object.
//Invoke the original console.log
return orgLog(message);
}
let a = {
foo: "bar"
};
console.log(a);
You tie into the stdout, stderr streams in the process module.
Take a look at npm capture-console. You will need to capture console output from any renderer process as well as the main process.
UPDATE
It appears electron has done some strange things with renderer process stdout stream. You are better off using a custom logging solution like electron-log and syncing logs from the written log file.

GET call failing in AngularJS resource - Strange data result

I have a simple angular resource that I've defined as below:
CompanyService.factory('CompanyService',
function ($resource) {
return $resource('https://baseurl.com/api/values/');
}
);
I then have a controller that calls that resource passing in a success and fail function:
.controller('companyList', function($scope, CompanyService) {
$scope.companies = CompanyService.query(
function(data) {
console.log(data);
return data;
},
function(error){
console.log("Error:");
console.log(error);
}
);
The rest API is a .NET MVC Web API that is extremely basic. I've configured it to return JSON and it simply returns an array of two objects like below. I've also enabled CORS so my angular app, which is hosted in a different domain, can call the api.
[{ID:1, Name:"TEST1"}, {ID:2, Name:"TEST2"}]
I've tested the REST call using jquery and just straight call through browser. All was functional (including the cross site scripting when calling from my angular app just using a straight JavaScript HTTP call).
When I try to call the api from my controller however, it always ends up in the error function. The error object contains a data property that is always populated with the string "resource is required|resource is required|undefined"
When I check the network I see no call to the values end point. It's as if the call is failing before ever being made.
If I change out the url to point to some sample REST api like https://jsonplaceholder.typicode.com/users/ it works fine and I'm able to see the call to "users" in the network traffic, which makes me think there is something wrong with my C# REST endpoint, however all my tests to call the REST endpoint outside of angular work successfully.
Can anyone help? I can't find anyone reporting this issues before anywhere on the net.
should the code be the one below? i didn't test it, just guess.
myModule.factory('CompanyService',
function ($resource) {
return $resource('https://baseurl.com/api/values/');
}
)
.controller('companyList', function($scope, CompanyService) {
CompanyService.query(
function(data) {
$scope.companies = data;
console.log(data);
return data;
},
function(error){
console.log("Error:");
console.log(error);
}
);
I ended up rebuilding my angular app from scratch. My first app was from the angular-seed github and had a handful of libraries already added in for testing and other things. One of those things is was was leading to this error as once I started a new project completely from scratch and added in angular and my REST call things worked perfectly. I've already spent too much time working through this so not going to spend any more time identifying exactly what it is but in case anyone else runs into the problem I did want to answer this one and close the book on it.

Passing and retrieving complex objects from Angularjs to Web Api

I have a form in angular where a user enters various criteria which I then want to pass to Web Api and get a result after queries are run. I originally thought of this as a "Get" but had trouble passing complex objects to the Web Api. With some advice, I then used a Post and was able to pass the criteria run the query in the Web Api but I had trouble getting the result back in Angular. The Web Api method is run and gets the results. But I don't see the results in the data service.
What is the best approach where the criteria for a query is multiple fields and some are lists? I haven't been able to find any good examples.
Here is the Web Api method:
[HttpPost]
public IEnumerable Post([FromBody] FrequentPawnerReportCriteria criteria)
{
var repo = new FrequentPawnerReport();
var result = repo.GetReport(criteria);
return result;
}`
Here is the dataservice:
function getFrequentPawner(criteria) {
return $http.post("/api/FrequentPawner/Post", criteria)
.then (getFrequentPawnerComplete)
.catch(getFrequentPawnerFailed);
function getFrequentPawnerComplete(response) {
var x = response
return response.data.results;
}
function getFrequentPawnerFailed(error) {
alert("XHR failed for frequent pawner report: " + error.responseText);
}
}
And here is the controller code:
function getTopPawnerResults(criteria) {
return DataContext.getFrequentPawner(criteria)
.then(
function (result) {
vm.frequentPawnerReport = result.data;
return vm.frequentPawnerReport;
});
}
Simply use JSON. Use JSON.stringify() to parse JSON object to string and POST it. Similarly, return JSON string from server, and assign it to variable in Angular. It will be automatically converted to JSON object.
I think when you make your post request, you need to have a callback function that would get invoked when your Web Api returns. Within that callback function you can update your $scope variables which will make your web ui show the response from the server. You can find an example of what I mean here: https://docs.angularjs.org/api/ng/service/$http
The gist of it:
$http({
method: 'POST',
url: '/path/to/your/web/api',
function(success) {
console.log('Successfully executed the api call');
$scope.response = response; // change this to match the data you are expecting from the server response
},
function(failure) {
console.error('There was an error');
$scope.failure = failure; // change this to match your failure response
}
);
Thanks for responding. The project is a mix of web forms and angularjs. I am migrating the app and didn't notice this form had a conflict which was causing a post back and making it look like the result was not being returned. I took the form into a separate project and was able to get the results I was going for.

getting backend flash messages from SPA frontend

I found it is very hard to deal with flash message returned from backend when working with single-page-application.
Say there are five actions:
login, logout,search,add,delete.
each action emits messages(successful or failed,could be more). in a Non-SPA, it is easy enough to do something like backend.getFlash() in the template to get the message stored in session.
However, in SPA, if the results are returned in JSON, and of course backend can pass the message to a js framework, say angularjs. But it is really tedious and not flexible at all.
Does anyone have any idea or experience?
Thanks
From your question I understood that what you really want is to have some messages for every actions, say for delete you need to display a message like "Deleted Successfully" and you don't want this message to be send along with the result set from your backend.
In AngularJS you can achieve this by having a service for showing the messages.
Here is an example;
Create a service like this in AngularJS
app.factory('FlashService', function ($rootScope) {
return {
show: function (message) {
$rootScope.flash = message;
return message;
},
clear: function () {
$rootScope.flash = '';
return null;
}
};
});
Here FlashService is the name of the service you are creating, don't bother about the name you can give any name of your choice.
To use this service inject it anywhere you want like;
var app = angular.module("your app name", []);
app.controller("MyCtrl", function(FlashService) {
FlashService.show("I am here");
});
And use it in your html like
<div id="flash">{{flash}}</div>

Get HTTP request time in angular.js?

I am trying to get the duration of each HTTP request I send through Angular.js, to so I can send it to New Relic analytics. I can use transformRequest to find when any HTTP request is fired, and I can use responseInterceptors to get the completed request. But I can't find any way to link that information together.
Any suggestions to get the duration of HTTP requests? Ideally something that works with Angularjs Rails Resource: https://github.com/FineLinePrototyping/angularjs-rails-resource?
I got this code from one of the blogs for rendering overlays by default when an http request is made. I modified it a little bit to address your issue. See if this helps.
angular
.module('analytics', [])
.config(function($httpProvider) {
$httpProvider.responseInterceptors.push(function() {
return function(promise) {
// START YOUR TIMER
var callReturn = function(r) {
// END YOUR TIMER
total_time = START TIMER - END TIMER
};
return promise.then(callReturn, callReturn);
};
});
});

Resources