I am new to using of web worker API in angularjs, I want to know the flow sequence for the web worker in angularjs, i.e., should I write services, then use them in controller and so on.. please i want to know flow sequence...
Yes, the question is very general.
But for those, who need to implement a particular task in angular environment I can recommend plugin https://github.com/vkiryukhin/ng-vkthread It let you easily export a function in a thread, execute it and get result in UI.
something like this:
/* function to execute in a thread */
function foo(n, m){
return n + m;
}
/* create an object, which you pass to vkThread as an argument*/
var param = {
fn: foo // <-- function to execute
args: [1, 2] // <-- arguments for this function
};
/* run thread */
vkThread.exec(param).then(
function (data) {
console.log(data); // <-- thread returns 3
},
function(err) {
alert(err); // <-- thread returns error message
}
);
see live demo at: http://www.eslinstructor.net/ng-vkthread/demo/
contact me on github if you have any questions
Related
I am facing a weird case, I am using google directionsService.route. but it doesn’t sync well. Here is my code:
angular.forEach(requestArray, function(v, i) {
directionsService.route(v, function(result, status) {
var googleLeg = result.routes[0].legs[0];
// sth else...
});
});
As you can see, I am looping the location Array into the route. every time I fire the function, it will go through the requestArray first, (if we make a breakpoint on the line (var googleLeg = result.routes[0].legs[0]), it doesn’t reach there until it goes through all the requestArray.(i from 0 - length); then it will have the second loop for directionsService.route( at this time, it will reach to line(var googleLeg = result.routes[0].legs[0]); Any idea about this?
Essentially your problem is that calling a google service is an asynchronous call, and you are not guaranteed when the callback will execute. If you need to process requestArray synchronously, here is what you can do:
function start() {
// create a copy of request array
var stuff = [].slice.call(requestArray);
function continueSync() {
// stop the recursion if we have nothing left to process
if (!stuff || stuff.length == 0) return;
// grab the first item off of the stuff queue
v = stuff[0];
stuff = stuff.slice(1);
// call to google
directionsService.route(v, function(result, status) {
var googleLeg = result.routes[0].legs[0];
// sth else...
// now continue processing the rest of the stuff queue through tail recursion
continueSync();
});
}
// kick off our recursive processing
continueSync();
}
your problem is that calling a google service is an asynchronous call, you could prove to generate threads
I am handling very hight dataset with type arry. While iterating through this arrays my application gets performance hit. I want to use webworkers which will perform manipulation operations on huge array and it will directly return the processed dataset back to application.web
Take a look at https://github.com/vkiryukhin/ng-vkthread I develop it exactly for such kind of tasks. It let you easily export function in a thread, execute it and get result in UI. Even more: you can download data directly in a thread rather than transfer it from UI to a thread.
the very basic usage is:
/* function to execute in a thread */
function foo(n, m){
return n + m;
}
/* create an object, which you pass to vkThread as an argument*/
var param = {
fn: foo // <-- function to execute
args: [1, 2] // <-- arguments for this function
};
/* run thread */
vkThread.exec(param).then(
function (data) {
console.log(data); // <-- thread returns 3
},
function(err) {
alert(err); // <-- thread returns error message
}
);
Doc and examples: http://www.eslinstructor.net/ng-vkthread/demo/
I have this JSON example:
$scope.channels = {
"ch1": {
id: "ch1",
data: {}
},
"ch2": {
id: "ch2",
data: {}
}
};
QUE 1
How do I update the data: {} part with the dynamic key ?
something like:
for ( var c in $scope.channels ) {
$http.get(JSON_PATH + c + '.json').then(function(res){
// DOES NOT WORK
$scope.channels[c]["data"] = res.data;
// ALSO DOES NOT WORK
var section = $scope.channels[c];
section.data = res.data;
$scope.channels[c] = section;
});
}
The result of $scope.channels is now to have a new section called "data" instead of being under the key == "ch1" (i.e).
In addition, Sublime Text 3 also gives a warning which I'm not sure why? ( it's not like I'm using this or something:
181 don't make functions within a loop
QUE 2
I solved the above problem by actually create an external function and call it within the loop.
So I was wondering why the above code in Que1 doesn't work, while this does:
function load_data(id) {
$http.get(JSON_PATH + c + '.json').then(function(res){
var section = $scope.channels[c];
var section.data = res.data;
$scope.channels[c] = section; // WORK
});
}
for ( var c in $scope.channels ) {
load_data(c);
}
In Que 1 the for loop has continued it's cycle while the $http method is asyncronously processing. The "c" variable has lost it's original context and value. I believe it is destroyed once the for loop completes.
In Que 2, "c" is now "id", and has been passed in as a static value that will continue to be available to anything inside the function closure regardless of asyncronous activity. The function makes a reference to "c" and ceases to care whether the loop destroys it or not.
This has to do with function closures, and will need someone with a better understanding to explain it in detail.
You should change "c" to "id" in Que 2 though, inside your function.
Also, as a semi-related side note, if you are going to loop a series of $http calls, you might want to look up the $q.all documentation and read about how to build promise arrays where you can detect resolution of all calls rather than just individual calls. It can be quite useful.
I currently have 2 pages, page1.php and page2.php, each of the pages uses a controller that completes its own functions etc.
However there are tabs within the pages that are exactly the same that gets a promise from a factory within the module. The lists are exactly the same except for querying on different IDs. For example both controllers have this:
pageListFactory.getData().then(function (result) {
$scope.BasicItems = result; $scope.basicItemsList = [];
angular.forEach($scope.BasicItems, function (BasicItem) {
angular.forEach(BasicItem['SomeInnerArray'], function (BasicSomeInnerItem) {
if (BasicSomeInnerItem == VARIABLE_THAT_CHANGES) {
$scope.basicItemsList.push({
ID: BasicItem.ID, Title: BasicItem.Title
});
}
});
});
});
So this code is used, and the VARIABLE_THAT_CHANGES is just what changes each time. However as I said it is used on multiple pages, is there a way to create just one function call and then each page just can call a specific bit and send the variable with it?
I tried using $rootScope but of course this just clogs and slows, and I'm not exactly happy on constantly using $rootScope to pass the $scope.basicItemsList around as the list could get quite big.
So is there any way to reuse this code without just copying and pasting it into each controller?
Sure you can re-use it...
Convert the factory to a service, its basically a name change, create a local variable to store the data, update the data on first call, and then grab the data if it exists on the second call.
.service('myService', ... stuff ... { // I suggest using a service, as I don't know if a factory would act as a singleton
var myData = null;
return {
getData: function(){
if(myData != null)
return myData; // returns data
else {
return $http()... // ajax call returns promise
}
},
setData: function(dataToSet){
myData = dataToSet;
}
}
Then your controllers:
//controller 1
var promiseOrData = pageListFactory.getData();
if(promiseOrData instanceOf Array){ // or whatever data you expect
$scope.BasicItems = promiseOrData;
....
}
else { // should be a promise
promiseOrData.then(function (result) {
pageListFactory.setData(result); // set the data once you get it.
$scope.BasicItems = result; $scope.basicItemsList = [];
....
}
}
In controller 2 you only need to get the data as the returned data will be an array, not a promise
On top of all this, write a directive which will process the data when you pass it along, then you can pass the variableThatChanges and have the directive take care of it.
Use services and write the function in that service and pass the variable VARIABLE_THAT_CHANGES into it. By this you can reuse the code.
I would like to interact with a REST API using $resource but when calling the save method I get has no method '$save' error. My code is inspired by the answer found on AngularJS $resource RESTful example
myapp.factory('Monitoring', function($resource) {
return $resource('http://localhost:8080/wepapp/network/v1/cronjobs/:id', { id: '#id' } );
});
Q1: What is the purpose of # in { id: '#id' }? I found it in most of the examples.
myapp.factory('MonitoringCRUDControllerService', ['Monitoring', function(Monitoring) {
return {
create: function(id, command, schedule) {
console.log("create");
console.log(command);
console.log(schedule);
Monitoring.id = id;
Monitoring.command = command;
Monitoring.schedule = schedule;
console.log(Monitoring);
Monitoring.$save();
}
}
}]);
The Monitoring object is correctly injected:
function Resource(value){
copy(value || {}, this);
}
Calling the $save failed with the error has no method '$save'.
Q2: What the purpose of $ before save?
Q3: What am I missing to make the save method work?
You need to create an instance of your Monitoring class like this (not tested):
var m = new Monitoring({id:id});
m.command = command;
m.schedule = schedule;
m.$save();
The documentation (http://docs.angularjs.org/api/ngResource.$resource) has a similar example:
var newCard = new CreditCard({number:'0123'});
newCard.name = "Mike Smith";
newCard.$save();
I asked the same question about the # sign a while ago: "at" sign in parameter names in resource definition. Basically # sign means that the value will be read from the object's property. Or as the same documentation says:
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).
The $ is not any special character, it is just a part of the method name.