cancel
Showing results for 
Search instead for 
Did you mean: 

Route and Targin Error:Cannot read property 'getPath' of undefined

naotoxxx
Participant
0 Kudos

Hello community i'm getting an error when i want to route with parameters i read over and over but i can't find what's wrong

ListInvoice.controller.js?eval:38 Uncaught TypeError: Cannot read property 'getPath' of undefined

this is my code

manifest

	"routing": {
	  "config": {
		"routerClass": "sap.m.routing.Router",
		"viewType": "XML",
		"viewPath": "kauf.databinding.app.view",
		"controlId": "apx",
		"controlAggregation": "pages",
		"async": true
	  },
	  "routes": [
		{
		  "pattern": "",
		  "name": "main",
		  "target": "main"
		},
		{
		  "pattern": "detail/{invoicePath}",
		  "name": "detail",
		  "target": "detail"
		}
	  ],
	  "targets": {
		"main": {
		  "viewID": "main",
		  "viewName": "Main"
		},
		"detail": {
		  "viewId": "detail",
		  "viewName": "Detail"
		}
	  }
	}

Component.js

sap.ui.define([
   "sap/ui/core/UIComponent"
], function (UIComponent, JSONModel) {
   "use strict";
   return UIComponent.extend("kauf.databinding.app.Component", {
	   	
	   metadata : {
           manifest: "json"
     },
		
      init : function () {
         // call the init function of the parent
         UIComponent.prototype.init.apply(this, arguments);
         
         	// create the views based on the url/hash
			this.getRouter().initialize();


	}
   });
});

the listinvoice where i'm calling the route detail and i already add this to an objectlistitem

type="Navigation" press="onPress"

listinvoice.view

<mvc:View 
		controllerName="kauf.databinding.app.controller.ListInvoice"
		xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
		xmlns:html="http://www.w3.org/1999/xhtml">
	
	
	<List headerText="{i18n>listTit}"
		  class="sapUiResponsiveMargin"
      	  width="auto"
      	  id="listaInvo"
      	  items="{
      	  			path: 'invoice.old>/Invoices',
      	  			sorter: {
      	  						path: 'ShipperName',
      	  						descending: false,
      	  						group: true
      	  					}
      	  			}">
      	  
      	<headerToolbar>
      		<Toolbar title="{i18n>invoiceListTitle}">
      		<ToolbarSpacer/>
      		<SearchField width="50%" search="onBuscarFiltro"/>
			</Toolbar>
      	</headerToolbar>  
	
		<items>
			<ObjectListItem
				title="{invoice.old>Quantity} x {invoice.old>ProductName}"
				
				number="{
					parts: [{path: 'invoice.old>ExtendedPrice'}, {path: 'view>/currency'}],
					type: 'sap.ui.model.type.Currency',
					formatOptions: {
						showMeasure: false
					}
				}"
				numberUnit="{view>/currency}"
				numberState="{= ${invoice.old>ExtendedPrice} > 50 ? 'Error' : 'Success' }"
				type="Navigation"
				press="onPress">
			<firstStatus>
				<ObjectStatus text="{	path: 'invoice.old>Status',
										formatter: '.formatter.statusText'}"/><!-- un "." delante del formatter significa que la función se busca en el controlador de la vista actual -->
			</firstStatus>
			</ObjectListItem>
		</items>
	
	</List>
		


</mvc:View>

listinvoice.controller

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"kauf/databinding/app/model/formatter",
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator",
	"sap/m/MessageToast"
], function (Controller, JSONModel, formatter, Filter, FilterOperator, MessageToast) {
	"use strict";
	
	return Controller.extend("kauf.databinding.app.controller.ListInvoice", {
		
		formatter : formatter, // PAra que este disponible en la vista
		
		onInit : function () {
			var oViewModel = new JSONModel({
				currency: "EUR"
			});
			this.getView().setModel(oViewModel,"view");
		},
		
		onBuscarFiltro : function (oEvent){ 
			var oArray = []; 
			var sQuery = oEvent.getParameter("query"); 
			if (sQuery) { 
				oArray.push(new Filter("ProductName", FilterOperator.Contains, sQuery)); 
			}
			
			var oList = this.byId("listaInvo"); 
			var oBinding = oList.getBinding("items");
			oBinding.filter(oArray);
		},
		onPress: function (oEvent) {
			var oItem = oEvent.getSource();
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
			oRouter.navTo("detail", {
				invoicePath: oItem.getBindingContext("invoice").getPath().substr(1)
			});
		}
	});
});

so in my detail.controller i have this , my detail.view just have a text with hard code

sap.ui.define([
	"sap/ui/core/mvc/Controller"
], function (Controller) {
	"use strict";
	return Controller.extend("kauf.databinding.app.controller.Detail", {
		onInit: function () {
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this); // Traemos la instancia del router "app" 
			oRouter.getRoute("detail").attachPatternMatched(this._onObjectMatched, this); // y lo ligamos a la route "detail" con attachPatternMatched 
																						  //en la route a la cual accedimos por el nombre registrmos una 
																						  //funcion interna que devolvera la ruta cuando esta sea llamada o por medio de url
		},
		
		_onObjectMatched: function (oEvent) { // Recibimos un parametro que usaremos para acceder a la url y parametros de navegacion
			this.getView().bindElement({ //accedemos al invoicePath que enviamos en el controlador de listinvoice y ,llamamos la funcion en la vista bindElmente para enviar el contexto
				path: "/" + oEvent.getParameter("arguments").invoicePath, // le agregamos el / que se quito en el listinvoice
				model: "invoice"
			});
		}
	});
});

.

Accepted Solutions (0)

Answers (3)

Answers (3)

Bernard
Participant
0 Kudos

You have assumed that this line of code in your ListInvoice controller

var oItem = oEvent.getSource();

gives you the item. That is not correct.

First get the path and then get the object (oItem) that maps to that path:

var sPath = oEvent.getSource().getBindingContext("invoice").getPath();
var oItem = this.getModel("invoice").getProperty(sPath); // you don't really seem to need this given your code

// you could use a value of any of the fields to navigate to detail if you 
// handled that in your detail controller (as opposed to the path) (e.g. invoice number)

Your navigation should then look like the below:

oRouter.navTo("detail", { invoicePath: sPath().substr(1)});
naotoxxx
Participant
0 Kudos

i tried like below, and still having the same error

onPress: function (oEvent) {
			var sPath = oEvent.getSource().getBindingContext("invoice").getPath();
			var oItem = this.getModel("invoice").getProperty(sPath);
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
			oRouter.navTo("detail", { invoicePath: sPath().substr(1)});

Bernard
Participant
0 Kudos

sorry - i didn't check my typing- should be

sPath.substr(1); 

not

sPath().substr(1)
Bernard
Participant
0 Kudos

Where is your onPress being triggered from (or by what)?

naotoxxx
Participant
0 Kudos

i updated my post and put my listinvoice.view, it's called by ObjectListItem

Bernard
Participant
0 Kudos

are you still getting the error: Cannot read property 'getPath' of undefined?

Are you using the correct model name: in your case (based on your view) it should be: invoice.old

var sPath = oEvent.getSource().getBindingContext("invoice.old").getPath();

Don't usually see a full stop "." in a model name - hope that's not problematic.

naotoxxx
Participant
0 Kudos

i changed the name of my model (in my manifest) to invoiceold so in my view insted invoice.old y changed to invoiceold and in my listinvoice.controller now is this:

			var sPath = oEvent.getSource().getBindingContext("invoiceold").getPath();
			var oItem = this.getModel("invoiceold").getProperty(sPath);
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
			oRouter.navTo("detail", { invoicePath: sPath().substr(1)});

and now, i'm getting error :

Uncaught TypeError: this.getModel is not a function
    at f.onPress (ListInvoice.controller.js?eval:35)
    at f.a.fireEvent (EventProvider-dbg.js:229)
    at f.a.fireEvent (Element-dbg.js:427)
    at f.firePress (ManagedObjectMetadata-dbg.js:428)

Bernard
Participant
0 Kudos
this.getView().getModel("invoiceold").getProperty(sPath);

Please add getView() in front of getModel("invoiceold") - see above

naotoxxx
Participant
0 Kudos

i got a error : sPath is not a function

this is the code that i modified with your suggest:

var sPath = oEvent.getSource().getBindingContext("invoiceold").getPath();
var oItem = this.getView().getModel("invoiceold").getProperty(sPath);

ChrisSolomon
Active Contributor
0 Kudos

Yes, as Jun said, we need to see your view code. It looks like the code in your controller (listinvoice.controller) is similar/same to that of the SAPUI5 "Walk-through" tutorial...around like step 33 or so. That code is dependent on your view having the "invoice" model assigned so it can then find the location/path in that model to the selected table item (ie. getBindingContext("invoice").getPath().substr(1) ).

naotoxxx
Participant
0 Kudos

you mean this:

listinvoice.view

	<List headerText="{i18n>listTit}"
		  class="sapUiResponsiveMargin"
      	  width="auto"
      	  id="listaInvo"
      	  items="{
      	  			path: 'invoice.old>/Invoices',
      	  			sorter: {
      	  						path: 'ShipperName',
      	  						descending: false,
      	  						group: true
      	  					}
      	  			}">
      	  
      	<headerToolbar>
      		<Toolbar title="{i18n>invoiceListTitle}">
      		<ToolbarSpacer/>
      		<SearchField width="50%" search="onBuscarFiltro"/>
			</Toolbar>
      	</headerToolbar>  
	
		<items>
			<ObjectListItem
				title="{invoice.old>Quantity} x {invoice.old>ProductName}"
				
				number="{
					parts: [{path: 'invoice.old>ExtendedPrice'}, {path: 'view>/currency'}],
					type: 'sap.ui.model.type.Currency',
					formatOptions: {
						showMeasure: false
					}
				}"
				numberUnit="{view>/currency}"
				numberState="{= ${invoice.old>ExtendedPrice} > 50 ? 'Error' : 'Success' }"
				type="Navigation"
				press="onPress">
			<firstStatus>
				<ObjectStatus text="{	path: 'invoice.old>Status',
										formatter: '.formatter.statusText'}"/><!-- un "." delante del formatter significa que la función se busca en el controlador de la vista actual -->
			</firstStatus>
			</ObjectListItem>
		</items>
	
	</List>

that listinvoice.old is a model refer to a Invoice.json . Here in my manifest:

	  "invoice.old": {
		"type": "sap.ui.model.json.JSONModel",
		"uri": "Invoices.json"
	  },

and this is my Invoice.json, it's something wrong with it?

{
  "Invoices": [
	{
	  "ProductName": "Pineapple",
	  "Quantity": 21,
	  "ExtendedPrice": 87.2000,
	  "ShipperName": "Fun Inc.",
	  "ShippedDate": "2015-04-01T00:00:00",
	  "Status": "A"
	},
	{
	  "ProductName": "Milk",
	  "Quantity": 4,
	  "ExtendedPrice": 9.99999,
	  "ShipperName": "ACME",
	  "ShippedDate": "2015-02-18T00:00:00",
	  "Status": "B"
	},
	{
	  "ProductName": "Canned Beans",
	  "Quantity": 3,
	  "ExtendedPrice": 6.85000,
	  "ShipperName": "ACME",
	  "ShippedDate": "2015-03-02T00:00:00",
	  "Status": "B"
	},
	{
	  "ProductName": "Salad",
	  "Quantity": 2,
	  "ExtendedPrice": 8.8000,
	  "ShipperName": "ACME",
	  "ShippedDate": "2015-04-12T00:00:00",
	  "Status": "C"
	},
	{
	  "ProductName": "Bread",
	  "Quantity": 1,
	  "ExtendedPrice": 2.71212,
	  "ShipperName": "Fun Inc.",
	  "ShippedDate": "2015-01-27T00:00:00",
	  "Status": "A"
	}
  ]
}

ChrisSolomon
Active Contributor
0 Kudos

There it is...the name you use in your controller does not match.

in controller, the model is called "invoice"...

oRouter.navTo("detail", {
				invoicePath: oItem.getBindingContext("invoice").getPath().substr(1)});

...but in your binding, it is "invoice.old".

naotoxxx
Participant
0 Kudos

i changed my name model to invoiceold and the refer in the view and now this is my code on listtinvoce.controller

		onPress: function (oEvent) {
			var sPath = oEvent.getSource().getBindingContext("invoiceold").getPath();
			var oItem = this.getView().getModel("invoiceold").getProperty(sPath);
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
			oRouter.navTo("detail", { invoicePath: sPath().substr(1)});

junwu
Active Contributor
0 Kudos
show me the code for view ListInvoice
naotoxxx
Participant
0 Kudos

it's already there, but is this:

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"kauf/databinding/app/model/formatter",
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator",
	"sap/m/MessageToast"
], function (Controller, JSONModel, formatter, Filter, FilterOperator, MessageToast) {
	"use strict";
	
	return Controller.extend("kauf.databinding.app.controller.ListInvoice", {
		
		formatter : formatter, // PAra que este disponible en la vista
		
		onInit : function () {
			var oViewModel = new JSONModel({
				currency: "EUR"
			});
			this.getView().setModel(oViewModel,"view");
		},
		
		onBuscarFiltro : function (oEvent){ 
			var oArray = []; 
			var sQuery = oEvent.getParameter("query"); 
			if (sQuery) { 
				oArray.push(new Filter("ProductName", FilterOperator.Contains, sQuery)); 
			}
			
			var oList = this.byId("listaInvo"); 
			var oBinding = oList.getBinding("items");
			oBinding.filter(oArray);
		},
		onPress: function (oEvent) {
			var oItem = oEvent.getSource();
			var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
			oRouter.navTo("detail", {
				invoicePath: oItem.getBindingContext("invoice").getPath().substr(1)
			});
		}
	});
});
junwu
Active Contributor
0 Kudos

VIEW , not controller......dude