Error in SAPUI5 routing / binding with 1.18 SDK example: SplitApp - sapui5

When testing the SplitApp demo app provided with the 1.18.5 SAPUI5 SDK there seems to be a conflict between the routing and model binding. If you navigate to a detail page and then refresh the browser window the data binding fails. This would be the same as if you bookmarked the app on a specific view.
Just wondering if anyone knows why this is? Is it a conflict with routing and data binding? My debugging is not showing anything up yet only that the model is empty when the detail view loads.
This app uses the new Component-based router where you define your routes in the component metadata.
I've also written a small test app here js1972/test · GitHub (branch "routes") which does similar and has the same issue.

the following bookmark works with the fake service
../test-routes/#/detail/Categories(2)
../test-routes/#/detail/Categories(3)
doesnt
request.onSend in ODataModelFakeService.js doesnt cater for all scenarios
an alternative maybe to use sap.ui.core.util.MockServer with a cutdown metadata.xml and json files for the Category and Product entities

I've ran into the same issue and just want to share my findings and solution:
The detail view waits until the list in the master view is loaded. If the service you are using is quite slow the list has already finsihed loading, but the model has not finished loading and thus the detail view returns an error.
To fix this I've attached an "requestCompleted"-event to the model and created a jQuery.Deferred object for the model.
The master then waits for the resolve of the model.
oModel.attachEvent("requestCompleted",
function() {
this.oModelFinishedDeferred.resolve();
this.getEventBus().publish("Model",
"ModelFinished");}
, this);

Related

Issues with WebIDE CRUD template and OData errors

Has anyone successfully based an application off the WebIDE Fiori CRUD template? It doesn't seem to be able to handle errors in the batch OData request properly.
For example when you select an item in the master list and click EDIT to update it and I enter a value that I know will cause an error in the backend. The batch OData request is sent and the response is successful (overall) even though internally the update failed. You see a bad request 400 error in the console but the app doesn't react to it.
Using the ErrorHandler.js object you can easily code a message box to show a nice error message, however the app seems to get confused and always navigates to the top item in the list but the ODataModel still has pending changes so if you try to navigate it shows the data loss dialog.
Trying to debug it is very painful given the nature of the code with Promises inside promises inside promises and callbacks firing everywhere!!
Maybe there is a better example CRUD application to base your apps on?
Well.... Some more debugging and I've found that all of the weird issues occurring with the Fiori CRUD template are due to the model defaulting to auto refreshing after changes.
Which typically is a nice feature as the user does not have to hit the refresh button to see changes that have been made after adding a new entry or editing an object.
But this auto refresh on the model seems to play havoc with updates in batch mode.
Firstly, if the batch update is completely successful the app navigates to the first item in the master list - which is should not.
Secondly, when there is an error in the batch of sorts of weird shit happens.
So to fix this I just call oModel.setRefreshAfterChange(false) before the oModel.submitChanges() call (only when updating, not creating). The in the callback after the save is completed we reset auto refresh to true.
The crud app now works as expected and can correctly handle errors in the odata batch update without strange ui updates.
Jason,
but the error message they are providing is very simple, and does not support parsing error body like :
<code>005056A509B11ED199D882461C8C40FE</code><message xml:lang="en">The Data Services Request version '3.0' is not supported for the request payload.</message><
we have to do the code for parsing the errors then show in the message box

Using iron-router with angular-meteor makes controllers being loaded twice

I have a Meteor application using angular-meteor. I need now to load different angular modules depending on url. I added iron-router to my application to do so and I continue to handle routes for each module using ngRoute and anchor nav but it behaves strangely if url contains params. I made a small test case which is available here:
https://github.com/clouchtibat/iron-router-ng-route
If you click on 'truc' link and then on 'test', next routes changes will make controller be instantiated two times. It works if urls have no params.
I also tested with ui-router (in the with-ui-router branch) and the problem is the same but in addition view is duplicated.
Is this a bug in one of the two routers or is there something wrong with my implementation?
Take a look at this conversations in the angular-meteor Github issues:
https://github.com/Urigo/angular-meteor/issues/154
https://github.com/Urigo/angular-meteor/issues/493
I think it can help you with some directions.
I am also having some hard time with mixin angular-meteor and iron:router.

How to implement cross app navigation and navigating back to the Fiori launchpad home?

In our company, we've set up the Fiori launchpad. In it, we have configured a tile that is linked to a custom developed SAPUI5 app, which is deployed as a BSP on the server. It took us a long while, yet using the router pattern within that application, we managed to make the navigation from the launchpad tile to the custom UI5 application work.
The thing we are struggling with, however, are these 2 other navigation paths:
From the application back to the Fiori launchpad (back home)
From the application to another application (tile to tile)
Ideally, this out of application navigation is in the UI5 way, including a transition, so not just a window.replace in JS. After a long search, the only hint I've found in support for this scenario is in this class:
https://ui5.sap.com/#/api/sap.ushell.services.CrossApplicationNavigation
However, I don't understand how to use it. The example isn't even correct and has syntax errors. I've found two forum posts elsewhere asking about how to use it, but they lack any meaningful answer.
Assuming you are using Semantic Objects for in-place navigation configured in your Launchpad to navigate to UI5 Applications you can navigate from one Application to another using the CrossApplicationNavigation service you already mentioned. However, the documentation about it is slightly confusing. This is how it works for me:
// Step 1: Get Service for app to app navigation
var navigationService = sap.ushell.Container.getService("CrossApplicationNavigation");
// Step 2: Navigate using your semantic object
navigationService.toExternal({
target : { semanticObject : "<YourObject>", action: "<YourAction>" },
params : { A : "B" } // optionally
})
If you want to go back to your launchpad after in-place navigation you simply need to call
window.history.go(-1)
This still triggers the correct transition.

Single page application cache issue

I have an single page application created in MVVM and knockout,typescript technology.
I am using knockout templating for creating different views within a Page.
The application Page has a view which shows a list of tasks user can start,pause,resume tasks.accordingly status changes using knockout.The database is getting updated but the UI doesnt reflect changes.
This application works fine in chrome but in IE the page doesn't get refreshed.In IE when from settings i choose request for new version of stored pages everytime.It works fine in IE also.
can any one help me out with a solution for this problem
It seems that your problem with the non-refreshing UI is a json caching problem.
Try to disable jquery ajax caching
$.ajaxSetup({ cache: false });
globally or just temporarily for the request which causes the problem.
IE is caching JSON responses, you wil find your response as a .json file in the temporary internet files folder :)
More information can be read here

Stopping Ember.js Controller

My question is very basic on one hand but on the other hand the general situation is more complex, plus I cannot really get any working sample.
I'm developing/maintaing a web-application which is currently in transition from GWT code base into Ember.js.
Most of the newer code already relies on Ember.js and I think it's really awesome.
The problem is we cannot use Ember Router as all the request are being handled by the GWT.
In order to enabled the application run in this unusual configuration we have special JavaScript files that create our Ember main objects (Controllers & Models) for us.
As you can imagine navigation between tabs is cumbersome and is handled by GWT who creates Ember objects when needed. We are in transit toward a brave new world Ember Router and all.
But in the meantime, this is the problem I'm facing right now.
The user clicks a link which opens a page that contains some Ember based table.
The data is retrieved form the server using some Ajax code. Upon success it spawns a forEach loop which tries to pushObject all the received date into our Ember based components.
My problem happens when the user quickly switches between tabs. In this case the first list of object has not finished rendering yet and suddenly there's a new set of objects to handle. This causes Ember to throw errors like:
"Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM. "
and
"Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist."
Is it possible to prevent the loop from trying to render?
I've tried checking if the controller in question is already inDOM and it is, is there a way to notify Ember this object is no longer valid?
Sorry for a lengthy question and lack of running sample.
I'd probably modify the switch tab code to only execute afterRender has completed, that way you aren't mucking with ember objects while they are being used.
Ember.run.scheduleOnce('afterRender', this, function(){
// call GWT switch tab routine
});
Thank you Daniel and Márcio Rodrigues Correa Júnior. eventually what I did is to add a patch that would check the current context of the application (in my case the currently selected tab). If upon receiving the AJAX response the application is in the correct context (meaning the user haven't change the tab) go on. Otherwise just ignore the response and do not try to render it.
Now it seems to be working