Is it possible to bind two models to one control? - sapui5

I need to display two numbers in my StandardTile. The data source is a SOAP web service, which I had to call twice with different parameters to obtain these two numbers. Is there any way to fill the tile with these two figures? I tried creating one XMLModel per each ajax call to the web service, and then binding the property of the control to the node from the response, but I'm just getting the same figure duplicated.
Below is my onInit method in the controller
onInit: function () {
// callback from ajax request
SOAPRequester.getMessageOverview(function (data) {
var oModel = new sap.ui.model.xml.XMLModel();
oModel.setData(data);
var oStandardTile = sap.ui.getCore().byId("__xmlview0--messageOverviewTile");
if (oStandardTile !== undefined) {
oStandardTile.setModel(oModel, "overview");
oStandardTile.bindProperty("number", {
path: "/SOAP-ENV:Body/rpl:getMessageListResponse/Response/rn5:number",
model: "overview"
});
}
});
//callback from the second ajax call
SOAPRequester.getErrorMessages(function (callbackData) {
var oModel = new sap.ui.model.xml.XMLModel();
oModel.setData(callbackData);
var oStandardTile = sap.ui.getCore().byId("__xmlview0--messageOverviewTile");
if (oStandardTile !== undefined) {
oStandardTile.setModel(oModel, "overview");
oStandardTile.bindProperty("infoState", "Error");
oStandardTile.bindProperty("info", {
path: "/SOAP-ENV:Body/rpl:getMessageListResponse/Response/rn5:number",
model: "overview"
});
}
});
},

Yes, it is. You are using the same model name twice, thus the firs one is not visible anymore. Simply use different model name, i.e. "overview" and "overview2" or what ever you prefer:
onInit: function () {
// callback from ajax request
SOAPRequester.getMessageOverview(function (data) {
var oModel = new sap.ui.model.xml.XMLModel();
oModel.setData(data);
var oStandardTile = sap.ui.getCore().byId("__xmlview0--messageOverviewTile");
if (oStandardTile !== undefined) {
oStandardTile.setModel(oModel, "overview");
oStandardTile.bindProperty("number", {
path: "/SOAP-ENV:Body/rpl:getMessageListResponse/Response/rn5:number",
model: "overview"
});
}
});
//callback from the second ajax call
SOAPRequester.getErrorMessages(function (callbackData) {
var oModel = new sap.ui.model.xml.XMLModel();
oModel.setData(callbackData);
var oStandardTile = sap.ui.getCore().byId("__xmlview0--messageOverviewTile");
if (oStandardTile !== undefined) {
oStandardTile.setModel(oModel, "overview2");
oStandardTile.bindProperty("infoState", "Error");
oStandardTile.bindProperty("info", {
path: "/SOAP-ENV:Body/rpl:getMessageListResponse/Response/rn5:number",
model: "overview2"
});
}
});
},
Hint: You could also improve your code a little, i.e.
call this.getView().byId("messageOverviewTile") or if you have the right UI5 version this.byId("messageOverviewTile") instead of sap.ui.getCore().byId("__xmlview0--messageOverviewTile")
Do the binding for your controls in your view and then in onInit() call this.getView().setModel(oModel, "overview") and this.getView().setModel(oModel, "overview2")

Related

Not able to initilize the JS view in openui5

Not able to initilize the below JS view in index page. Could you please help me?
I m getting this error msg "Uncaught (in promise) TypeError: t.createContent is not a function"
Plunker link:
https://plnkr.co/edit/7v0CN93aDrAOY9WqU269?p=preview
app.view.js:
sap.ui.jsview("app",{
getControllerName:function(){
return "app";
},
createContent:function(oContoller){
var oButton = new sap.m.Button(this.createId("helloButton"),{
text:"Click Me"
});
return oButton;
}
});
change the view code like this
sap.ui.jsview("view.js.app", {
getControllerName: function() {
return "view.js.app";
},
createContent: function(oContoller) {
var oButton = new sap.m.Button(this.createId("helloButton"), {
text: "Click Me"
});
return oButton;
}
});
Also add a controller file app.controller.js and paste below code.
sap.ui.controller("view.js.app", {
onInit: function() {
}
});
You are specifying the resourceroots as "view.js" in the index file.
So while instantiating use below code
var view = sap.ui.view({
id:"idApp1",
type:sap.ui.core.mvc.ViewType.JS,
viewName:"view.js.app"
});
And in the view add these changes,
sap.ui.jsview("view.js.app",{
getControllerName:function(){
return "view.js.app";
},
createContent:function(oContoller){
var oButton = new sap.m.Button(this.createId("helloButton"),{
text:"Click Me"
});
return oButton;
}
});
And add one controller file named app as below,
sap.ui.define(["sap/ui/core/mvc/Controller"],
function (Controller) {
"use strict";
return Controller.extend("view.js.app", {
});
});
Here is the working link.

Unable to use page objects in my spec file in protractor

//This is my AngularPage.cs page object file
var AngularPage= function()
{
var nameInput= element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get=function()
{
browser.get('http://www.angularjs.org');
};
this.setName= function(name)
{
nameInput.sendKeys(name);
};
this.getGreeting= function()
{
return greeting.getText();`
};
};
module.exports = new AngularPage();
//This is my AngularHome_spec.js file
var angularPage = require('./AngularPage.js');
describe('angularjs homepage',function()
{
var angular_page;
beforeEach(function()
{
angular_page= new AngularPage();
});
it('greetings for new user', function()
{
// var angular_page= new AngularPage();
angular_page.get();
angular_page.setName('Rahul');
expect(angular_page.getGreeting()).toEqual('Hello Rahul!');
}
);
}
);
//I am unable to use page objects in my spec file as it is throwing an error
:AngularPage is not defined
In your code, object has been created twice. First time on page "AngularPage.js" and second time on spec "AngularHome_spec.js" level.
Do following on page "AngularHome_spec.js"
module.exports = AngularPage;
Change the
var AngularPage = require('./AngularPage.js');//Capital the 'A'

SAPUI5 and NW Portal

I have an SAPUI5 application deployed on my portal.
I am trying get the user login logged on portal in my SAPUI5.
But when I run my application it is not get any data.
Bellow is my code
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/Fragment',
'sap/ui/core/mvc/Controller',
'sap/ui/model/Filter',
'sap/ui/model/json/JSONModel'
], function(jQuery, Fragment, Controller, Filter, JSONModel) {
"use strict";
var CController = Controller.extend("sap.m.ZHRUI001.C", {
inputId: '',
valueHelpRequest: function(oController) {
this.inputId = oController.oSource.sId;
var sServiceUrl = "http://<my server host>:<my server port>/sap/bc/ui2/start_up";
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, "user", "password");
var oJsonModel = new sap.ui.model.json.JSONModel();
oModel.read("/?", null, null, true, function(oData, response) {
oJsonModel.setData(oData);
});
sap.ui.getCore().setModel(oJsonModel);
// Handling of both confirm and cancel; clear the filter
var that = this;
var handleClose = function(oEvent) {
var oSelectedItem = oEvent.getParameter("selectedItem");
if (oSelectedItem) {
that.byId(that.inputId).setValue(oSelectedItem.getTitle());
}
oEvent.getSource().getBinding("items").filter([]);
};
// Create a SelectDialog and display it; bind to the same
// model as for the suggested items
if (!this._valueHelpSelectDialog) {
this._valueHelpSelectDialog = new sap.m.SelectDialog("valueHelpSelectDialog", {
title: "{fullName}",
items: {
template: new sap.m.StandardListItem({
title: "{fullName}",
active: true
})
},
search: function(oEvent) {
var sValue = oEvent.getParameter("value");
var oFilter = new sap.ui.model.Filter(
"name",
sap.ui.model.FilterOperator.Contains, sValue
);
oEvent.getSource().getBinding("items").filter([oFilter]);
},
confirm: handleClose,
cancel: handleClose
});
this._valueHelpSelectDialog.setModel(oJsonModel);
} else {
this._valueHelpSelectDialog.setModel(oJsonModel);
}
this._valueHelpSelectDialog.open();
}
});
return CController;
});
From what I'm reading you are speaking of a SAP Portal, I expect you have a 7.3+ version.
I have found the SAP doc you used to find the user, be careful because this is not the code for a SAPUI5 application running on a portal but for one running on a R/3 system, the endpoint /sap/bc/ui2/start_up doesn't exist on a NetWeaver portal.
What you could do is develop a simple REST service (by developping a Servlet) that will send back the user and all the details that you need.
These details can be found in the PortalComponentRequest which holds a IUser object, you can find a sample portal servlet on my Git here :
https://gitlab.com/Almiriad/sap-portal-samples
You simply have to send a GET request to the url
http[s]://youserver:your port/irj/servlet/prt/portal/prtroot/UserServletSample.UserInfoSampleServlet
and you'll get a JSo
{
"user": {
"user-name":"<LASTNAME>, <FIRSTNAME>",
"user-id":"<USER_ID>",
"user-email":"<USER#EMAIL.COM>"
}
}
I hope this will help you.
`
var oUserData;
var y = "/sap/bc/ui2/start_up";
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
oUserData = JSON.parse(xmlHttp.responseText);
}
};
xmlHttp.open("GET", y, false);
xmlHttp.send(null);
`
console oUserData to get login details of that user who logged in.

Debugging Ember-cli-mirage when routes are not being called

I have successfully created one route in ember-cli-mirage, but am having trouble loading the related data.
The API should be returning JSON API compliant data.
I'm not really sure if there are any good methods or not for debugging mirage's request interception. Here is my config.js
export default function() {
this.urlPrefix = 'https://myserver/';
this.namespace = 'api/v1';
this.get('/machines', function(db, request) {
return {
data: db.machines.map(attrs => (
{
type: 'machines',
id: attrs.id,
attributes: attrs
}
))
};
});
this.get('/machines/:id', function(db, request){
let id = request.params.id;
debugger;
return {
data: {
type: 'machines',
id: id,
attributes: db.machines.find(id),
relationships:{
"service-orders": db["service-orders"].where({machineId: id})
}
}
};
});
this.get('/machines/:machine_id/service-orders', function(db, request){
debugger; // this never gets caught
});
}
Most of this is working fine (I think). I can create machines and service orders in the factory and see the db object being updated. However, where my application would normally make a call to the api for service-orders: //myserver/machines/:machine_id/service-orders, the request is not caught and nothing goes out to the API
EDIT:
This is the route that my Ember app is using for /machines/:machine_id/service-orders:
export default Ember.Route.extend(MachineFunctionalRouteMixin, {
model: function() {
var machine = this.modelFor('machines.show');
var serviceOrders = machine.get('serviceOrders');
return serviceOrders;
},
setupController: function(controller, model) {
this._super(controller, model);
}
});
And the model for machines/show:
export default Ember.Route.extend({
model: function(params) {
var machine = this.store.find('machine', params.machine_id);
return machine;
},
setupController: function(controller, model) {
this._super(controller, model);
var machinesController = this.controllerFor('machines');
machinesController.set('attrs.currentMachine', model);
}
});
Intuitively, I would think that machine.get('serviceOrders'); would make a call to the API that would be intercepted and handled by Mirage. Which does not seem to be the case

Updating presentation layer when the mongo document changes

I have a list of dogs in a table that have an underlying dog model and dog collection. When I update the dogName of a dog document in the mongo collection I want the table list item to update and show the new dog name without having to refresh the page.
I thought this was supposed to happen when you this.listenTo(this.model, 'change', this.render);
How can I get the table row item to update when the model changes??
window.Dog = Backbone.Model.extend({
urlRoot: "/dogs",
idAttribute:"_id",
initialize: function() {
}
defaults:{
_id: null,
dogName: "",
}
});
window.DogCollection = Backbone.Collection.extend({
model: Dog,
url: "/dogs/user/",
});
window.DogListView = Backbone.View.extend({
initialize: function () {
this.listenTo(this.model, 'change', this.render);
this.render();
},
render: function () {
var dogs = this.model.models;
$(this.el).html(this.template());
for (var i = 0; i < dogs.length; i++) {
this.$('#dogsTable tbody').append(
new DogListItemView({model: dogs[i], no: i+1}).render().el
);
}
this.$('#dogsTable').dataTable({
"bAutoWidth": false,"iDisplayLength": 50
});
return this;
}
});
window.DogListItemView = Backbone.View.extend({
tagName: "tr",
initialize: function (options) {
this.listenTo(this.model, 'change', this.render);
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
this.no = options.no;
this.render();
},
render: function () {
$(this.el).html(this.template({
no: this.no,
id: this.model.get("_id"),
dogName: this.model.get("dogName"),
}));
return this;
},
events: {
"click .delete": "deleteDog",
}
});
And finally in backbone controller I use this to load the view:
var dogList = new DogCollection();
dogList.url = "/dogs/user/" + this.user.get("_id");
dogList.fetch({
success: function() {
$('#content').html(new DogListView({model: dogList}).el);
}
});
What you're doing right now is:
Create some views (item- and collectionViews)
Define a collection
Set an url for this collection
Fetch the collection and on succes
Display the fetched data in these views
This is totally fine and these views will (probably, did not test your code) update once a change occurs in any of your models in the collection.
However, your application has no way of knowing that something is changed in your mongo database once it has fetched the data. If you would like to obtain this functionality, you could do for example one of the following;
Make the collection poll (and thus refetch) once in a while.
Inform your application that something has changed on the server using websockets. If you'd like to do this, you can use a library like http://socket.io