Is it really required to listen for global init event using "attachInit" function? - sapui5

I read it in many articles that, "it is a good practice to listen for global init event in order to trigger your application logic only after the event has been fired". But I tried to do otherwise still no problem occurs. When I check the network tab all, irrespective of the placement of the code, the core libraries are loaded first. Then the code dependent on libraries is loaded.
I tried searching for my answer but couldn't get a clear answer. I tried to check it using a sample code I wrote. But no success.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta charset="UTF-8">
<title>My Pets</title>
<script id="test"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m">
</script>
<script>
var oImage2 = new sap.m.Image({
src: "img/cat_sad.jpg",
decorative: false,
alt: "sad cat"
});
oImage2.placeAt("content");
alert("different_script_tag");
</script>
<script>
sap.ui.getCore().attachInit(function() {
alert("inside_attachinit");
var oImage1 = new sap.m.Image({
src: "img/dog_sad.jpg",
decorative: false,
alt: "sad dog"
});
oImage1.placeAt("content");
});
alert("outside_attachinit");
</script>
</head>
<body id="content" class="sapUiBody">
</body>
</html>
I wish to know, if browser already prioritizes the requests accordingly for us, why we are told to follow this good practice?

It is not only "a good practice", it's absolutely necessary in order to enable asynchronous loading.
Activating asynchronous loading of modules requires listening to the init event. Otherwise, the app will crash because you're trying to access Image from sap.m although that library hasn't been loaded yet:
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-async="true"
></script>
<script>
var oImage2 = new sap.m.Image(/*...*/); // Uncaught TypeError: Cannot read property 'Image' of undefined!
</script>
If you're wondering why asynchronous loading is important, compare these two scenarios:
1. Without listening to init (no aync possible):
Dependent libraries and other modules are retrieved sequentially one by one.
It uses sync XHR which is deprecated.
While the app loads, browser often freezes.
Users usually need to wait longer until they see something.
2. With async (listening to init required):
Files are retrieved in parallel asynchronously.
No freezing behavior.
Depending on synchronous XHR is not future-proof and makes the app significantly slower. As UI5 is getting better and better and preparing for further improvements, please keep following best-practices in order to "evolve" together with UI5.

Related

Configuring URL parameters in run configurations

My team is migrating to SAP BAS from SAP Web IDE. But when making run configurations I could not find how to configure something important to us: where to configure URL parameters like we could in the Web IDE.
I've consulted several pieces of SAP documentation such as this guide, but came away empty handed. The UI5 CLI also doesn't seem to offer anything interesting in this regard.
Does anyone know whether configuring URL parameters in run configurations is still possible, if necessary in the raw corresponding .env files?
Thank you in advance,
Joshua
I don`t know if you found yet how to do this but in any case, the solution that i found was to modify the Index.HTML file called and put a little piece of Script code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EXTRATOCLIENTE</title>
<script id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize" data-sap-ui-resourceroots='{"br.com.araguaia.EXTRATOCLIENTE": "./"}'
data-sap-ui-compatVersion="edge" data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-async="true" data-sap-ui-frameOptions="trusted">
</script>
<script>
var oStartupParameters = jQuery.sap.getUriParameters().mParams;
var oComponent = sap.ui.getCore().createComponent({
name: "br.com.araguaia.EXTRATOCLIENTE",
settings: {
componentData: { startupParameters: oStartupParameters }
}
});
new sap.ui.core.ComponentContainer({
component: oComponent
}).placeAt("content");
</script>
</head>
<body class="sapUiBody" id="content">
</body>
</html>
After that you can put some parameter on the url like this :
index.html?Kunnr='123'&Kkber='ACRA'
Renan Pacheco
I also found a quick-and-dirty way to run with URL parameters. Run configurations are saved in the .vscode/launch.json file. In that file, there's an args array associated with each run configuration with a mention of the index.html file of your project. You can manually append your desired URL parameters to it.
There is a package.json which is created when you create any application.
It contains the script to start. You can add your URL parameters here.

Prevent caching of pages?

I've noticed while I deploy my flutter web project with nginx, after doing a "flutter build web" that if I don't delete the cache the old files are still in my chrome browser. Is there a way to force a refresh for users automatically if I deploy updates?
Every browser does caching and is completely normal when you don't immediately see the changes on the client browser. It does take some time for the browser to realize the code has been changed on the server and needs to update its local cache. And is completely depends on the client browser settings and client's connection speed.
But if your situations demand the client to have an updated version of the website in no time, there is a workaround.
The main.dart.js file is something like this below
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Flutter App</title>
</head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
In order to force browsers to reload the app each time we want that, add a unique parameter to the main.dart.js script-src (for example a version, though it can be anything, even just a random number after ?). The new index.html will look like:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Flutter App</title>
</head>
<body>
<script src="main.dart.js?version=1" type="application/javascript"></script>
</body>
</html>
Cons:
You have to manually add the incremented version number every time you want to deploy. Maybe you can write a script for doing that.
It does still take time if the client has slow internet connection. The problem arises when browsers like Chrome show Lite(cached) version of the website untill internet connection is fast enough.
Previous versions still persist to live on the client's browser till timeout

creating html to call Bing Maps

I inherited some code that worked with Bing Maps v6 so I'm now trying to reproduce functionality in v8. I did the following as an initial attempt, but even this doesn't seem to work. (I've tried to follow https://social.technet.microsoft.com/wiki/contents/articles/34568.bing-maps-v6-3-to-v8-migration-guide.aspx along with various other bits I've found online, but I'm coming into this with no knowledge at all of Bing maps, so I've erred in apparently significant ways since this gets no results. Happy for all guidance.
I've omitted our Bing key below, but other than that, this is the code I attempted to use.
<!DOCTYPE html>
<html>
<head>
<title>Title here</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
</head>
<body>
<div id='myMap' style='width: 100vw; height: 100vh;'></div>
<script type='text/javascript'>
var map;
function loadMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'BingKeyOmittedHereForSecurityPurposes'
});
map.Geocode('Jericho, VT', GeocodeCallback);
}
function GeocodeCallback(layer, results, places, hasMore, veErrorMessage) {
// no idea what should be here
}
</script>
<script type='text/javascript'
src='https://www.bing.com/api/maps/mapcontrol?callback=loadMap' async defer></script>
</body>
</html>
I'll be adding Pins and possible directions once I get this working, but figured I should get the basics working before getting fancy.
The map doesn't have a geocode function, instead you have to use the search module. Bing Maps V7 and above break out additional functionalities using modules. This makes for a much lighter page load compared to V6 which had every possible feature crammed into a single downloaded file.
In any case here is a sample of how to geocode in V8. https://github.com/Microsoft/BingMapsV8CodeSamples/blob/master/Samples/Search/Geocode.html
Here are some resources to help you with your migration:
Bing Maps V8 code samples
Bing Maps V6.3 to V8 Migration Guide

system.js fail to properly display error messages from babel

When I setup a very simple project with jspm using system.js and babel, it seems that the error messages are not correctly displayed.
I did the following :
npm init; press enter a bunch of times
jspm init; press enter a bunch of times
And added two files :
index.html
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="jspm_packages/system.js" type="text/javascript"></script>
<script src="config.js" type="text/javascript"></script>
<script type="text/javascript">
console.log('test 1');
System.import('main');
</script>
</head>
<body>
</body>
</html>
main.js
console.log('test2);
// ^ I voluntarily forgot the ' to show the error;
According to this talk, and previous experiences with babel, I should see some very nice syntax error messages, like this one :
But instead, I got this, which is completely cryptic, and doesn't help me a bit :
Because of the error line saying system.js:1:0, I believe the error happens in system.js, and it fails before calling babel.
Moreover, I noticed es6-module-loader isn't loaded. I thought it was used in system.js.
I don't see what I am missing here.

Can I use Coffeescript in client side too?

Is there any way to use CoffeeScript in client side?
There are two ways:
Compile the CoffeeScript to JavaScript and deploy it as you would any JavaScript file, or
Use coffee-script.js, which allows you to put <script type="text/coffeescript> tags in your page.
The latter isn't recommended for production use, but it's nice for development. Or for usage in online editors like these:
<script crossorigin src="https://coffeescript.org/v2/browser-compiler-legacy/coffeescript.js"></script>
<script type="text/coffeescript">
console.log 'Hello World!'
</script>
See the related question: Is there a way to send CoffeeScript to the client's browser and have it compiled to JavaScript *there*?
See also Webmake plugin for CoffeeScript -> https://github.com/medikoo/webmake-coffee
It allows you to organize coffee modules in Node.js style and bundle it for browser. It provides source maps support, so you can debug CoffeeScript files as they are, directly in a browser.
To not compile everytime you can use -w param and coffee will compile the file everytime file change
coffee -wco src/ public/js
Yes, it can be done by adding a CoffeeScript src tag to the head section of your html page.
Download the CoffeeScript source from this path: http://coffeescript.org/extras/coffee-script.js
Copy and paste the below code and try to run in a browser:
<html>
<head>
<script type="text/javascript">
function printHelloJava(){
alert("Hello Javascript");
}
</script>
<script src="coffee-script.js"></script>
<script type="text/coffeescript">
#printHello = ->
alert "Hello Coffee Script"
</script>
</head>
<body>
<h1>Coffee Script on client side</h1>
<input type="button" onclick="printHelloJava();" value="Hello Java">
<br>
<input type="button" onclick="printHello()" value="Hello Coffee">
</body>
</html>
You can also use CDN coffeescript for better and faster performance.
<script src="http://cdnjs.cloudflare.com/ajax/libs/coffee-script/1.7.1/coffee-script.min.js"></script>
or
<script src="https://cdn.rawgit.com/jashkenas/coffeescript/1.11.1/extras/coffee-script.js"></script>
Then use type="text/coffeescript" for compile Coffee Script.
<script type="text/coffeescript">
// add code here
</script>