Event to find out all feature successfully loaded to the layer - openlayers-6

I am using OpenLayers6 to load the map on my website. How can I know if all the features in the geojson file completed the loading to the layer?
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
url: "test.geojson",
format: new ol.format.GeoJSON(),
}),
style: function(feature) {
return style;
}
});
map.addLayer(layer);
Is there any event to know that I have completed the loading of all feature inside the "test.geojson" to the layer?

Related

React Native Uploading Video to YouTube (Stuck at Processing)

I am attempting to upload video files to YouTube using their v3 API and their MediaUploader. It works in my ReactJS application, but not in my React Native application. When uploading via React Native, the upload completes, then stalls at 100%. In my YouTube account, I can see the new video file, but it is stuck at "Video is still being processed."
I believe the issue may be that I need to send a video file and not an object with a video uri but I don't know how to get around that.
I am using the YouTube MediaUploader from the CORS example at https://github.com/youtube/api-samples/blob/master/javascript/cors_upload.js I am using an OAuth 2.0 client Id, and this setup works correctly when using the ReactJS app via my website. I am using React Native Expo with Camera, which returns me an Object with a URI, for example:
Video File: Object {
"uri": "file:///var/mobile/Containers/Data/Application/353A7969-E2A8-4C80-B641-C80B2B029555/Library/Caches/ExponentExperienceData/%2540dj_walksalot%252Fwandereo/Camera/E971DFEC-AB3E-4B6D-892F-9027AFE47A1A.mov",
}
This file can be viewed in the application, and I can even successfully send this to my server for playback on the web app and in the React Native app. However, sending this object in the MediaUploader does not work. It will take an appropriate amount of time to upload, but then sits at 100%, while my YouTube account will show it has received the video with the correct metadata, but the video itself remains stuck at "Video is still being processed."
video_file: Object {
"uri": "file:///var/mobile/Containers/Data/Application/353A7969-E2A8-4C80-B641-C80B2B029555/Library/Caches/ExponentExperienceData/%2540dj_walksalot%252Fwandereo/Camera/E971DFEC-AB3E-4B6D-892F-9027AFE47A1A.mov",
}
export const uploadToYouTube = (access_token, video_file, metadata) => async (dispatch) => {
...cors_upload...
var uploader = new MediaUploader({
baseUrl: `https://www.googleapis.com/upload/youtube/v3/videos?part=snippet%2Cstatus&key=API_KEY`,
file: video_file,
token: access_token,
metadata: metadata,
contentType: 'video/quicktime',
// contentType: 'application/octet-stream',//"video/*",
// contentType = options.contentType || this.file.type || 'application/octet-stream';
params: {
part: Object.keys(metadata).join(',')
},
onError: function(data) {
// onError code
let err = JSON.parse(data);
dispatch(returnErrors(err.message, err.code))
console.log('Error: ', err);
},
onProgress: function(progressEvent){
// onProgress code
let percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
dispatch({
type: UPLOAD_PROGRESS,
payload: percentCompleted
});
},
onComplete: function(data) {
console.log('Complete');
// onComplete code
let responseData = JSON.parse(data);
dispatch({
type: UPLOAD_YOUTUBE_VIDEO,
payload: JSON.parse(data)
})
dispatch({
type: UPLOAD_PROGRESS,
payload: 0
});
}
});
uploader.upload();
}
Similar to my currently-working web app, after completing the upload, the "onComplete" function should fire, and YouTube should process the video. This does not happen. I believe it's because I'm attaching an object with a URI and not the actual file.
I was able to solve this from a post at Expert Mill by Joe Edgar at https://www.expertmill.com/2018/10/19/using-and-uploading-dynamically-created-local-files-in-react-native-and-expo/
By using fetch and .blob() I was able to convert the URI object to a data object and upload. Additional code:
const file = await fetch(video_file.uri);
const file_blob = await file.blob();
No need to install RNFetchBlob since this is in the Expo SDK.

Workbox - runtime cache only created on second page refresh

I'm new to service workers, and I'm using Workbox to precache my app shell and cache my api data.
The precaching of assets is working correctly, with the cache being created and populated.
The runtime caching isn't creating a cache and populating it until I reload the page a second time.
I thought this might be a timing issue, so I set a page reload of the data in the javascript, however this still didn't cache the call.
I'm not doing anything specific to create the cache, app code is:
...
app.getData = function() {
var requestHeaders = new Headers({
Accept: "application/json"
});
fetch(app.dataUrl, { headers: requestHeaders })
.then(function(response) {
return response.json();
})
.then(function(json) {
app.updateCards(json);
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
});
}
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/my_sw.js')
.then(function() {
console.log('Service Worker Registered');
});
}
app.getData(); # fetch api data
then in the service worker:
...
const workboxSW = new self.WorkboxSW({clientsClaim: true});
// register data url to cache
workboxSW.router.registerRoute(
'/my_api/data',
workboxSW.strategies.staleWhileRevalidate()
);
// pre-cache assets
workboxSW.precache(fileManifest);
I am using the Chrome Dev tools to check the sw status and the cache created. The network calls to the data URL are as follows:
1st load of page:
2nd load of page:
I'd be grateful for any advice on what I'm doing wrong, or how to debug it.
Thanks in advance
Dan
To be safe, you might want to add skipWaitingto the Workbox constructor to ensure the service worker doesn't wait for the page to reload to start caching.
You would also want to wait on serviceWorker.ready in your page before making the API call. This way you know the service worker is active.
These changes together, in your service worker you would have:
...
const workboxSW = new self.WorkboxSW({skipWaiting: true, clientsClaim: true});
// register data url to cache
workboxSW.router.registerRoute(
'/my_api/data',
workboxSW.strategies.staleWhileRevalidate()
);
// pre-cache assets
workboxSW.precache(fileManifest);
Then in your web page
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/my_sw.js')
.then(function() {
return navigator.serviceWorker.ready;
})
.then(function() {
app.getData(); # fetch api data
});
}

Unable to upload form data and file contents on submit

I am attempting to use jQuery-File-Upload for showing the preview of the uploaded image. This is working fine. The code for file upload is as shown below
$('#Image').fileupload({
url : "/FileUpload/Upload",
autoupload:false,
add: function (e, data) {
gm.layout.loaderOpen(); //open loader
data.submit();
},
done: function (e, data) {
console.log("done")
if (data.response().jqXHR.status === 200)
$('#processImage').attr('src', data.response().jqXHR.responseText);
},
always: function (e, data) {
gm.layout.loaderClose();
}
})
However apart from the image preview the form also has other fields which the user fills up and then submits the form. Now I am trying to use ajax to submit and collect the data by serialzing the form
var formData = $('form').serializeArray();
$.ajax({
type:"POST",
url: "{url}",
data: formData,
contentType: false,
processData:false,
success: function (data) {
alert("whatever");
}
});
This ajax submit fails as long as I have the fileupload for the html input control. With the file upload the multimedia data doesn't reach the server on submit
However, in the absence of fileupload for the same control, everything works fine and I can get the file content on the server.
Any idea what I am doing wrong?

Laravel 5.1 and Backbone.js Application

I'm new in Backbone and I'm trying to build an app on top of an existing Laravel API. I understand the concept of every Backbone component (Model, Collection, View, Router), but I'm having a bit of trouble defining an architecture for my app. When a user logs in, it gets redirected to a dashboard, with a few options in a navbar.
var LeadsView = Backbone.View.extend({});
var SourcesView = Backbone.View.extend({});
var TeamsView = Backbone.View.extend({});
var AppRouter = Backbone.Router.extend({
routes: {
// navbar option Leads
"leads": "_leadsView",
// navbar option Sources
"sources": "_sourcesView",
// navbar option Teams
"teams": "_teamsView"
},
_leadsView: function() {
var leads = new LeadsView();
},
_sourcesView: function(query, page) {
var sources = new SourcesView();
},
_teamsView: function(query, page) {
var teams = new SourcesView();
},
});
I get that a Backbone View acts like a Controller in Laravel, so with each of these defined routes, there's a pointer to a View ( LeadsView, SourcesView, TeamsView). When any one of the views gets instantiated, that view will take care of the model/collection, UI binding, and every other logic for the app interaction. My question is ... Is This approach good, conventional ? If not, how can one use routes to bind each navigation option to an action in Backbone ?

How to properly initialize the JSON store in Worklight 6.1

I am attempting to initalize the IBM Worklight JSON store as below:
//JSONStore jsonStoreCollection metadata
var jsonStoreCollection = {};
//JSONStore jsonStoreCollection metadata
var COLLECTION_NAME = 'people';
function wlCommonInit(){
// Create empty options to pass to
// the WL.JSONStore.init function
var options = {};
//Define the collection and list the search fields
jsonStoreCollection[COLLECTION_NAME] = {
searchFields : {name: 'string'},
};
//Initialize the JSON store collection
WL.JSONStore.init(jsonStoreCollection, options)
.then(function () {
console.log("Successfully Initialized the JSON store");
})
.fail(function (errorObject) {
console.log("JSON store init failed :( ");
});
}
But when I run this in my android emulator the logcat gives me the "JSON store init failed" message. And the following error:
[wl.jsonstore {"src":"initCollection", "err":-2,"msg":"PROVISION_TABLE_SEARCH_FIELDS_MISMATCH","col":"token","usr":"jsonstore","doc":{},"res":{}}
This implementation seems to be very much what is outlined in the documentation, however I cannot get it to initialize.
Can anyone tell me what I am doing wrong here?
The documentation with the error codes is here.
-2 PROVISION_TABLE_SEARCH_FIELDS_MISMATCH
Search fields are not dynamic. It is not possible to change search fields without calling
the destroy method or the removeCollection method in the WL.JSONStore
class before calling the init method with the new search fields. This
error can occur if you change the name or type of the search field.
For example: {key: 'string'} to {key: 'number'} or {myKey: 'string'}
to {theKey: 'string'}.
No need to uninstall the application, just follow the documentation and handle that error case by calling removeCollection or destroy. For example:
WL.JSONStore.init(...)
.then(function () {
//init was successful
})
.fail(function (error) {
//check for -2
//call removeCollection or destroy
//re-init with new search fields
});
You can always submit a feature request to make this easier.
If you have previously created a JSON store with the same name but with different initialization variables. You must uninstall the application.
After uninstalling you can re-deploy the application to the device and the JSON store will initialize as expected.
Since discovering this, I have seen the issue a couple more times as I made changes to the configuration of my JSON store in my Worklight application.