Error in web worker using importScripts(defiant.min.js) - javascript

I'm trying to use defiant.js in a web worker, since I'm doing heavy computation in addition to the JSON.search.
However I keep getting a
Uncaught Error: Uncaught ReferenceError: Defiant is not defined
I created a simple example using part of the defiant demo code.
Does anyone know whether this is a defiant.js issue or am I just importing the script wrong?
Or is there another solution on how this can be done?
JS in main.html
var obj = {
"car": [
{"id": 10, "color": "silver", "name": "Volvo"},
{"id": 11, "color": "red", "name": "Saab"},
{"id": 12, "color": "red", "name": "Peugeot"},
{"id": 13, "color": "yellow", "name": "Porsche"}
],
"bike": [
{"id": 20, "color": "black", "name": "Cannondale"},
{"id": 21, "color": "red", "name": "Shimano"}
]
}
var worker = new Worker('defiantWW.js');
worker.addEventListener('message', function(e) {
console.log( e.data);
}, false);
worker.postMessage(obj);
web worker file
self.addEventListener('message', function(e) {
importScripts('defiant.min.js')
var obj=e.data;
var search = JSON.search(obj, '//car[color="yellow"]/name');
self.postMessage(search);
}, false);
EDIT
changing the position of importScripts() as suggested by dandavis in comments - but same result
web worker file v2
importScripts('defiant.min.js')
self.addEventListener('message', function(e) {
var obj=e.data;
var search = JSON.search(obj, '//car[color="yellow"]/name');
self.postMessage(search);
}, false);

Sadly enough defiantJS does not support the use within a web-worker.
Got feedback from Hakan Bilgin on the issue:
There is already support for web workers in Defiant.js
<script src="defiant.min.js"></script>
<script>
var obj = {
"car": [
{"id": 10, "color": "silver", "name": "Volvo"},
{"id": 11, "color": "red", "name": "Saab"},
{"id": 12, "color": "red", "name": "Peugeot"},
{"id": 13, "color": "yellow", "name": "Porsche"}
],
"bike": [
{"id": 20, "color": "black", "name": "Cannondale"},
{"id": 21, "color": "red", "name": "Shimano"}
]
};
Defiant.getSnapshot(obj, function(snapshot) {
var found = JSON.search(snapshot, '//car');
console.log(found);
});
</script>
[Snapshot] doesn't give me access to defiant from within my own web-worker.
I can execute the Snapshot in the main thread and then post the result to my web-worker, however the large JSON (5-15mb) is handled only in the web-worker. I would have to pass it over to the main thread, run the Snapshot (which is executed in another web-worker) and then pass the result back to my WW.
Since I'm using the JSON.search quite often that would induce a lot of unnecessary overhead on the main thread.
No...you can not access Defiant from within a web worker

hi to load a service worker try this link:
https://developers.google.com/web/fundamentals/primers/service-workers
as it mentioned:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}

Related

Issues adding sessions and information to the Google Fit REST Api using JS

So I am reasonably new to using API's with Js but I am struggling a lot to understand how the Google Fit API works. I am attempting to add a new Workout's data to the API by adding a session and some data for the intensity (heart points) of the session. I can get the session to appear correctly but run into constant errors when I try to create a dataSource and add a point to it for the session. It would be greatly appreciated if someone could help me to fix my code to achieve this or could direct me to a more thorough example of similar code as the API docs don't seem to be too well detailed with examples etc. Thanks in advance.
Here's the 3 api calls that I have written so far, one for creating the DataSource, one for the DataPoint and one for the Session. The session works correctly and adds a session of 1 hr for the correct activity but I am unable to get any of the other API requests to work.
Data Source :
``gapi.client.fitness.users.dataSources.create({
"userId":"me",
"resource": {
"application": {
"name": "LittleWorkouts"
},
"dataType": {"field":[{
"format": "floatPoint",
"name": "com.google.heart_minutes"
}],
"name": "com.google.heart_minutes"
},
"device": {
"manufacturer": "op",
"model": "6",
"type": "phone",
"uid": "1000019",
"version": "1"
},
"type": "raw"
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 1", err); });
``
Data Point :
``
gapi.client.fitness.users.dataSources.datasets.patch({
"dataSourceId":"raw:com.google.heart_minutes:292824132082:op:6:1000019",
"userId": "me",
"datasetId": "1592087806561000000-1592287806561000000",
"resource": {
"minStartTimeNs": "1592087806561000000",
"maxEndTimeNs": "1592287806561000000",
"dataSourceId": "raw:com.google.heart_minutes:292824132082:op:6:1000019",
"point": [
{
"startTimeNanos": "1592087806561000000",
"endTimeNanos": "1592287806561000000",
"value": [
{
"fpVal": 89.1
}
],
"dataTypeName": "com.google.heart_minutes"
}
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 2", err); });
``
Session :
``gapi.client.fitness.users.sessions.update({
"userId":"me",
"sessionId": "someSessionId19",
"id": "someSessionId19",
"name": "Awesome Workout19",
"description": "A very intense workout",
"startTimeMillis": new Date().getTime() - 3600000,
"endTimeMillis": new Date().getTime(),
"version": 1,
"lastModifiedToken": "exampleToken",
"application": {
"detailsUrl": "http://example.com",
"name": "LittleWorkouts",
"version": "1.0"
},
"activityType": 21,
"activeTimeMillis": 3600000
}).then((res) => {console.log(res)});
console.log('res')
//request.execute((res) => {console.log(res);console.log('executrd')})
console.log(auth2.currentUser.get().getBasicProfile().getGivenName());
var request2 = gapi.client.fitness.users.sessions.list({
"userId":"me"
}).then((res) => {console.log(res)})
``
Error message
{message: "Unable to fetch DataSource for Dataset: raw:com.google.heart_minutes:292824132082:op:6:1000019", domain: "global", reason: "invalidArgument"}
It looks like it could be that you're trying to pass in the wrong fields for the data type: if you want to use a standard data type (like com.google.heart_minutes), you should either pass the exact fields of the standard data type (the field should be called "intensity"); or just pass the data type name, and the backend will fill them in for you.
So, if you change the data type to
"dataType": {"name": "com.google.heart_minutes"}
It should work.
Then, you need to use the data source ID returned from that request for the data points.
Awesome, so after some support in the comments I have some working code to add a new session with data from a previously defined data source using 3 API calls. The first call is to create a data source and only needs to be run once. The second and third then add a data point to a data set and creates a new session for the workout respectively. Here's the final working code:
Data Source:
/*
gapi.client.fitness.users.dataSources.create({
"userId":"me",
"resource": {
"application": {
"name": "LittleWorkouts"
},
"dataType": {
"name": "com.google.heart_minutes"
},
"device": {
"manufacturer": "op",
"model": "6",
"type": "phone",
"uid": "1000020",
"version": "1"
},
"type": "raw"
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 1", err); });
*/
Data and Data Set:
gapi.client.fitness.users.dataSources.datasets.patch({
"dataSourceId":"raw:com.google.heart_minutes:108881196053:op:6:1000020",
"userId": "me",
"datasetId": z,
"resource": {
"minStartTimeNs": workoutStartTime * 1000000,
"maxEndTimeNs": workoutEndTime * 1000000,
"dataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
"point": [
{
"originDataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
"value": [
{
"fpVal": 8
}
],
"dataTypeName": "com.google.heart_minutes",
"endTimeNanos": workoutEndTime * 1000000,
"startTimeNanos": workoutStartTime * 1000000,
}
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 2", err); });
Session:
gapi.client.fitness.users.sessions.update({
"userId":"me",
"sessionId": id,
"id": id,
"name": "Morning Workout",
"description": "A very intense workout",
"startTimeMillis": workoutStartTime,
"endTimeMillis": workoutEndTime,
"version": 1,
"lastModifiedToken": "exampleToken",
"application": {
"detailsUrl": "http://example.com",
"name": "LittleWorkouts",
"version": "1.0"
},
"activityType": 21,
"activeTimeMillis": workoutEndTime - workoutStartTime
}).then((res) => {console.log(res)});
console.log('res')

Cannot establish connection - source does not exist

I have a simple section in which users can connect from one element to another element as they wish. after connection can be like this. am using jsPlumb for connections.
After connections, if the user is satisfied he/she can save it,
everything is saved correctly as I want, now when user reload the page connections eg (con_6, con_18) are not displayed.
Here is json where the data are saved.
{
"movies": [
{
"left": 237,
"top": 99,
"movieid": "51"
},
{
"left": 241,
"top": 263,
"movieid": "10"
},
{
"left": 746,
"top": 184,
"movieid": "12"
}
],
"connections": [
{
"buttonid": "0",
"movieid": "12"
},
{
"buttonid": "4",
"movieid": "12"
}
]
}
Here is my function to load my connections
$.getJSON('datasaved/settings2.json', function (data) {
var flowchartconnection =data.connections;
for( var j = 0; j < flowchartconnection.length; j++ ) {
console.log(flowchartconnection[j].buttonid);
jsPlumb.connect({ source: flowchartconnection[j].buttonid, target: flowchartconnection[j].movieid });
console.log(jsPlumb.connect);
}
});
Unfortunately, I am getting the following error:
Cannot establish a connection - source does not exist.
Here is live demo :live demo
Here is js plumb connect function documentation: js plumb connect
Here is my console.log from my live demo : live demo
As you can see on the console the source and target id is available on the DOM before the connections happen,
Can you please tell me what am I doing wrong?

Display json response in ajax jquery,

The JSON Response I'm getting,
{
"user_data": {
"id": 22,
"first_name": xxx,
"last_name": xxx,
"phone_number": "123456789",
},
"question_with_answers" : [
{
"id": 1,
"question_name": "Features of our project that you like (select one
or more):",
"answers": [
{
"id": 19,
"question_id": 1,
"customer_id": 22,
"option": "Location",
},
{
"id": 20,
"question_id": 1,
"customer_id": 22,
"option": "Architecture",
},
]
},
{
"id": 2,
"question_name": "Features of our project that you DID NOT like
(select one or more):",
"answers": [
{
"id": 22,
"question_id": 2,
"customer_id": 22,
"option": "Location",
},
]
},
{
"id": 3,
"question_name": "How soon are you looking to buy a new home?",
"answers": [
{
"id": 24,
"question_id": 3,
"customer_id": 22,
"option": "Immediately",
}
]
}
]
}
So that is how JSON response looks like, now I need to display data using jquery
My js code
function openModal(Id){
var CustomerId = Id;
$.ajax({
type : 'get',
url: 'customer-details',
data: {
'CustomerId':CustomerId
},
success: function(data)
{
//what I have to do here
}
})
}
The output I want is,
first_name : xxx
last_name : xxx
phone_number : 123456789
1.Features of our project that you like (select one or more):
ans: Location, Architecture
2.Features of our project that you DID NOT like (select one or more)
ans: Location
3.How soon are you looking to buy a new home?
ans: Immediately
Thats how my output should look like from above json response,Is it possible to get above output using that Json response I got
There are two variable that I have passed from backend like user_data and question_with_answers
In success handler first of all make your json into a array using
var obj = JSON.parse(data);
Now in data you have array of your response and you can use this like
obj.first_name
obj.last_name
Note:- may be you have issue in JSON.parse so use first
var data = json.stringify(data)
after that use Json.parse function and use above data variable
this data
You have to set the dataType in the $.ajax call, set it to dataType:"json"...
After that, you got on the data variable in the success the json object and you can access it like data.user_data or data.id or data.first_name.
If you dont define the json as dataType, it will not work properly.
Addition
If you want to display the content of "question_with_answer" you have to iterate trough it, like ....
for (i in data.question_with_answer) { alert(data.qestion_with_answer[i]); }

Load external JSON file in PaperJS

I thought this would be really simple to do with:
project.importJSON('structures.json')
Unfortunately this gives me:
JSON Parse error: Unexpected identifier "structures"
This "structures" must come from the JSON file structures.json itself which looks like this:
{
"structures": [
{"name":"shed", "width": 4, "height": 3, "depth": 5},
{"name": "house", "width": 6, "height": 7, "depth": 5},
{"name": "factory", "width": 4, "height": 3.5, "depth": 6.5,
"depth_sub_1": 5.5,
"depth_sub_2": 4.5 }
]
}
Any ideas on how to make this work? I'd rather not use jQuery for this.
Edit
So it seems to me that using importJSON can only work when the JSON is an actual Paper object. The same error keeps on occurring.
What's the alternative? I want my external 'structural' data in what is basically a JavaScript file. Should I use the regular route for doing so?
My html looks something like this:
<head>
<script type="text/javascript" src="../../assets/javascript/paper-full.js"></script>
<script type="text/paperscript" src="I/a_view_on_my_structures.js" canvas="phase-I"></script>
</head>
<body>
<canvas id="phase-I" resize="true"></canvas>
</body>
You should stringify your data.
var structures = {
"structures": [
{"name":"shed", "width": 4, "height": 3, "depth": 5},
{"name": "house", "width": 6, "height": 7, "depth": 5},
{"name": "factory", "width": 4, "height": 3.5, "depth": 6.5,
"depth_sub_1": 5.5,
"depth_sub_2": 4.5 }
]
}
project.importJSON(JSON.stringify(structures))
if you json data is in a different file you should read that file first
This is how you read a file
synchronously
var client = new XMLHttpRequest();
client.open('GET', 'path/to/your/file', false);
client.onreadystatechange = function() {
//your data is in client.responseText
console.log(client.responseText);
}
client.send(null);
asynchronously
var client = new XMLHttpRequest();
client.open('GET', 'path/to/your/file');
client.onreadystatechange = function() {
//your data is in client.responseText
console.log(client.responseText);
}
client.send();
notice that when you do this, you don't need to stringify your data, because you read it as a text, so you just have to pass the client.responseText content to the importJSON function

How merge two objects array in angularjs?

I want to append following object array with existing one in angulajs for implementing load more feature.
ie,appending AJAX response with existing one each time.
I have one variable, $scope.actions which contains following JSON data,
{
"total": 13,
"per_page": 2,
"current_page": 1,
"last_page": 7,
"next_page_url": "http://invoice.local/activities/?page=2",
"prev_page_url": null,
"from": 1,
"to": 2,
"data": [
{
"id": 2108,
"action_type_id": 202,
"user_id": 1
},
{
"id": 2108,
"action_type_id": 202,
"user_id": 1
}
]
}
I want to append following JSON response each time this variable.
{
"data": [
{
"id": 2108,
"action_type_id": 202,
"user_id": 1
},
{
"id": 2108,
"action_type_id": 202,
"user_id": 1
}
]
}
I have tried with $scope.actions.data.concat(data.data);
but it is not working and getting following error message
$scope.actions.data.concat is not a function
You can use angular.extend(dest, src1, src2,...);
In your case it would be :
angular.extend($scope.actions.data, data);
See documentation here :
https://docs.angularjs.org/api/ng/function/angular.extend
Otherwise, if you only get new values from the server, you can do the following
for (var i=0; i<data.length; i++){
$scope.actions.data.push(data[i]);
}
This works for me :
$scope.array1 = $scope.array1.concat(array2)
In your case it would be :
$scope.actions.data = $scope.actions.data.concat(data)
$scope.actions.data.concat is not a function
same problem with me but i solve the problem by
$scope.actions.data = [].concat($scope.actions.data , data)
Simple
var a=[{a:4}], b=[{b:5}]
angular.merge(a,b) // [{a:4, b:5}]
Tested on angular 1.4.1

Categories

Resources