monaco-editor in AngularJS - angularjs

I am able to implement monaco-editor in AngularJS but in case if user refresh the page monaco through an error saying that "monaco is not defined" this is because monaco is loading lazy.Is there any other way monaco can load immediately. Here is the code..
resolve: {
srcipts: function (lazyScript) {
return lazyScript.register([
"monaco-editor/min/vs/loader.js",
"monaco-editor/min/vs/editor/editor.main.nls.js",
"monaco-editor/min/vs/editor/editor.main.js"
]).then(function () {
// console.log(require);
require.config({ paths: { 'vs': 'monaco-editor/min/vs' } })
// console.log(monaco)
})
}
}
this are the link to i refereed
Lazy-load MonacoEditor
https://github.com/Microsoft/monaco-editor/blob/master/docs/integrate-amd.md
https://microsoft.github.io/monaco-editor/playground.html
help me with this issue

This isn't exactly the answer you were looking for, but I had the same problem with monaco in Angular 1.x. I ended up implementing monaco inside of an iFrame. Makes it a bit difficult, but it loads much easier than with AMD loading.

I know it's far from an ideal solution, but I basically ended up doing the following in a Directive that wraps the editor.
function delayedInitialization() {
if (typeof window.monaco === 'undefined') {
$timeout(delayedInitialization, 200);
} else {
initialize();
}
}
One could perhaps make that a bit cleaner by packaging the editor in a way that allowed to listen for an event of sorts, but for now this works for our need.

Related

How to change title using ng-idle title directive

I'm trying to change the page title using ng-idle:
My title:
<title>MySite Local</title>
The code that doesn't seem to be working:
app.run(function (Title) {
Title.idleMessage('You are idle');
});
Taken from https://github.com/HackedByChinese/ng-idle/issues/128
Am I missing anything here? The title doesn't change without the above code either.
I've also got TitleProvider.enabled(true); just in case.
I'm not familiar with that directive, but if all you're trying to do is set the title, a plain old controller will work.
titleController.js
(() => {
"use strict"
angular.module('myApp').controller('titleController', titleController)
function titleController($scope) {
$scope.appTitle = "Hi Dad, I'm in jail!"
}
})()
index.html
{{appTitle}}
Of course, you'd have to add your own logic to detect an idle user.

How to add a custom error page in Cordova InAppBrowser or hide the error url?

pleas check this attached image I'm building an Ionic Android app with the InAppBrowser plugin. When the internet connection is not available, the plugin shows web page not available and requesting url.
Please help me customise the InAppBrowser error page (404 page). Or help me hide the requesting url.
Thank you.
I think I misunderstood your problem, first time, sorry about that. I'm reading again your problem and I'm figuring out what's happening. You need to add a custom configuration at config.xml to redirect to an error page when Cordova detect it. I hope this solve your problem.
<preference name="ErrorUrl" value="myErrorPage.html"/>
The original response works when you want to open a link through Cordova inAppBrowser plugin. If this doesn't sort out your problem, please reformulate your question.
Original response
You could be listening inAppBrowser events to figure what's happening.
Here, you can see how listen browser events, such as loaderror and manage the 404 error as you want. You must save a reference to inAppBrowser when open method is called, and then you could listen for error event.
function loadErrorCallBack(params) {
// Do stuff
}
inAppBrowserRef = cordova.InAppBrowser.open(url, target, options);
inAppBrowserRef.addEventListener('loaderror', loadErrorCallBack);
I am using Ionic 4 and I couldn’t manage to make the solution based on config.xml editing to work :
preference name="ErrorUrl" value="myErrorPage.html"/
Placing an addEventListener on loaderror didn’t work neither. It looks like it is not triggered by http errors and the plugin need a fix.
But we found a hack that is much simpler.
On loadstop we wait 500 milliseconds and then we get the loaded url by triggering executeScript with and window.location.href
If the loaded url is of the custom error page, in Cordova (not in IAB) we display a custom message with a back button.
It's a hack but that cover the requirement for now
I just came across the same problem and here's what I did. The code is for Android and works on IOS as well. But you would want to remove navigator.app.exitApp(); for IOS as Apple does not allow apps to take exit without pressing the home button.
Let me know if this works for you. It will hide default error page and open your custom error page. Write your own error code in myerrorpage.html
document.getElementById("openBrowser").addEventListener("click", openBrowser);
document.addEventListener("offline", onOffline, false);
function onOffline(e) {
e.preventDefault();
var src = 'myErrorPage.html';
var target = '_blank';
var option = "loaction=no, toolbar=no, zoom=no, hidden=yes, hardwareback=no";
var ref = cordova.InAppBrowser.open(src, target, option);
alert('Your device is Offline. Please check your connection and try again.');
navigator.app.exitApp();
}
function openBrowser() {
var url = 'https://www.yourlink.com';
var target = '_self';
var options = "location=no,toolbar=no,zoom=no, hardwareback=no, hidden=yes" ;
var ref = cordova.InAppBrowser.open(url, target, options);
}
When the components do not work, I perform the following procedure
ionic state reset
ionic platform remove android
ionic platform remove ios
ionic platform add android
ionic platform add ios
and try with ionicPlatform ready
<button class="button button-balanced" ng-click="OpenBrowser()">Test</button>
In controller
$scope.OpenBrowser = undefined;
$ionicPlatform.ready(function () {
$scope.OpenBrowser = function () {
$cordovaInAppBrowser.open('http://ngcordova.com', '_blank', options)
.then(function (event) {
})
.catch(function (event) {
$scope.Error = event;
});
};
});
I couldn't manage solution with setting ErrorUrl in Ionic 4 on Android to work.
Finally I came up with another solution - hide default error page and redirect user to any page (I use last page from event.url).
constructor(private iab: InAppBrowser) {
}
private openUrl(url: string)
{
this.platform.ready().then(() => {
if (this.platform.is('cordova')) {
this.openBrowser(url);
}
});
}
private openBrowser(url: string): InAppBrowserObject
{
const options: InAppBrowserOptions = {
location: 'no',
zoom: 'no',
hidden: 'no'
};
const browser = this.iab.create(url, '_blank', options);
browser.on('loaderror').subscribe(
event => this.onLoadError(event, browser)
);
return browser;
}
private onLoadError(event: InAppBrowserEvent, browser: InAppBrowserObject): void
{
browser.executeScript({
code: `
window.addEventListener('DOMContentLoaded', function () {
document.querySelector('body').style.background = 'black';
document.querySelector('body').innerHTML = '';
}, true);
window.addEventListener('load', function () {
window.location.replace('${event.url}');
}, true);
`,
}
).then();
}
Changing background and redirecting is tricky - from my experiments using injectCss won't work, because body is generated in the meantime. Using DOMContentLoader makes it black and clears text on screen.
But redirecting won't work in DOMContentLoader (don't ask me why), so you need to use load event.
It works great when user is using hardware back and returns to POST request - this way he will be redirected to GET of the same url (but you can use any url you want).

Global React does not play nice with AMD React

I'm getting weird weird behaviour when rendering a component using an AMD-loaded React, when a global React already exists on the page. Click events on components are getting fired when they should not be.
A look at the DOM implies that this stems from multiple React instances (one global, one AMD in my case) not being aware of each other, but this poses a problem when loading an AMD module at runtime that depends on React, into a page that also includes React.
How can I resolve this clash?
Reproduction
I can make a component like this:
var ButtonComponent = React.createClass({
onButtonClick: function(){
alert(this.props.data + ' click event fired');
},
render: function() {
return React.DOM.button({onClick: this.onButtonClick}, this.props.data);
}
});
(function(){ // create vanilla
var ButtonList = React.createClass({
render: function() {
return React.DOM.div({}, React.createElement(ButtonComponent, {data: this.props.data}));
}
});
React.render(React.createElement(ButtonList, {data: 'button that was loaded by the page'}), document.getElementById('page-load-target'));
})();
jsbin
But as soon as I add another component using another instance of React then click the first button, then it calls the click event on the second loaded button:
// .... as above ....
(function(){ // create using amd
require.config({
paths: {
'react': '//fb.me/react-with-addons-0.12.2.min'
}
});
window.setTimeout(function(){
require(['react'], function(ReactFromAmd){
ReactFromAmd.render(ReactFromAmd.createElement(ButtonComponent, {data: 'button that was loaded by AMD'}), document.getElementById('amd-load-target'));
});
}, 1000)
})();
jsbin
If I use the existing, global version of React in this call (rather than ReactFromAmd, then it works as expected. jsbin
The ancestors (React instance) of ButtonComponent and the component created with ReactFromAmd.createElement are different, and yet they are in the same virtual DOM -- That's not allowed.
If you don't mind replacing AMD with browserify, I just figured out a way to let isolated/remotely-loaded React components co-exist nicely.
(To be continued if someone needs it)
This has been fixed in version 0.14.2: http://jsbin.com/tesodoxape/1/edit?html,js,output

Proper way to create custom JS animations in angular 1.3+ with ng-animate

I want to use velocity.js in combination with ng-animate to create custom js-animations for my app. I've searched the web and found a lot of answers and tutorials which all refer to old versions of ng-animate, which apparently has changed the API a lot over time.
So right now, this is how my animation looks:
app.animation('.lb-fade', function () {
return {
addClass: function (element, className) {
element.velocity({
opacity: 1
},{
duration: 900,
easing: 'easeInSine'
});
}
};
});
I'm using it like this:
$animate.addClass(backdrop, 'lb-fade').then(console.log('promise resolved'));
This kind of works, but I have two problems:
The promise sometimes get's resolved to early (before the animation is finished). It looks like it is happening randomly.
How can I pass arguments to the animation? For example i want some of my lb-fade animations to use velocitys delay option. I could either create multiple animations (!DRY) or access the elements scope inside the animation (which seems really hacky to me). Is there a right way to do it?
Does it even make sense to use ng-animate alongside with velocity or should I just create my own functions to hold the animation code?
Maybe this is more like a workaround, but I wrote my own animator service now instead of using ngAnimate now. It uses angulars $q for implementing promises. Basically, this is just how ngAnimate does it, but somehow I think it doesn't know when velocity finished animating.
This is my service:
.service('animator', function animator($q) {
this.flyOutRight = function($element) {
return $q(function(resolve) {
$element.velocity({
//css properties to get animated
}, {
duration: 200,
complete: function () {
$element.remove();
resolve();
}
});
});
};
//some more animations
});
Usage:
animator.flyOutRight($oldImage).then(function(){
changeImageMutex = false;
});
It looks like you found a great workaround for your problem!
I think your original code didn't work since you didn't use the built-in done function. it's actually a wrapper for the default promise that ngAnimate returns at the end of an animation.
you used the function with the 2nd parameter className: function (element, className)
I used angular's ngAnimate as follows:
app.animation('.lb-fade', function () {
return {
addClass: function (element, doneFn) {
element.velocity({
opacity: 1
},{
duration: 900,
complete: doneFn
});
}
};
});
This works great for me.
It looks like the doneFn is still part of the api for ngAnimate.
Also, if you still want to use className (even though it looks like you didn't use it), you can use the function with it like so:
function(element, className, doneFn) {}

ExtJS 4.1: unload event

I am working with ext js 4.1. I am developing an application that have to support IE9, the latest Firefox, the latest Chrome and Safari.
I need to show an alert message when the user wants to leave the if there are some data that is pending to submit.
I did the following using raw Javascript:
window.onbeforeunload=function(){
if (Ext.getStore('LocalChangesStore')){
if (Ext.getStore('LocalChangesStore').getCount() > 0) {
return 'Your changes are be lost.';
}
}
};
I am wondering if that would be possible with ext js. I saw the following function:
app.js:
EventManager.onWindowUnload( function(){
if (Ext.getStore('LocalChangesStore')){
if (Ext.getStore('LocalChangesStore').getCount() > 0) {
return 'Your changes are be lost.';
}
}
}, this
);
but it did not work.
Can somebody let me know which would be the best approach to solve this issue?
The onWindowUnload method attachs a function to the unload event but what you need is attach a function to the beforeunload event. Try this please
Ext.EventManager.on(window, 'beforeunload', function() {
return 'Your changes are be lost.';
});
Good luck.

Resources