cancel
Showing results for 
Search instead for 
Did you mean: 

How to directly call an odata entity instance from SAP MDK application

joreddy
Explorer
0 Kudos

Hi,

I have a scenario in SAP MDK app where I need to directly call an user api from backed like /ZGR_GET_USERDETAIL('1234') on application initialization based on logged in user.

I tried to return the same from a rule like a string also as a readlink but still it doen't work.

Any help on this is appriciated.

Thanks.

Accepted Solutions (0)

Answers (2)

Answers (2)

bill_froelich
Product and Topic Expert
Product and Topic Expert

Here is an example rule that directly calls the entity and retrieves a property. It is using the sample service Product table. When applying to your service be sure to make sure your id value is the correct data type for the entity.

/**
 * Describe this function...
 * @param {IClientAPI} context
 */
 export default function DirectEntityReadTest(context) {
    console.log('DirectEntityReadTest');
    let productId = '06ccaa6e-ae41-48d2-8557-6c4497c41bfb';
    return context.read('/SalesOrder/Services/Sample.service',`Products('${productId}')`,[]).then(function(results) {
        console.log('Read Success');
        if (results.length > 0) {
            let prod = results.getItem(0);
            console.log(`Product Name: ${prod.Name}`);
            return context.executeAction({
                'Name': "/SalesOrder/Actions/GenericToastMessage.action",
                'Properties': {
                    "Message": `Product Name: ${prod.Name}`
                }
            });
        }
    });
}
Padmindra
Explorer
0 Kudos

Hi Bill,

I tried with same sample example to run the odata in my project. Still getting the error as "Could not find the service provider". ClientAPI.read is not working as expected.

Code:

 let customerId = 'c2d465a9-30b0-49d7-96d4-e564f681df82';
 return clientAPI.read('/dynamicApp/Services/sampleData.service', `Customers('${customerId}')`, []).then(function (results) {
     console.log('Read Success');
     if (results.length > 0) {
         let prod = results.getItem(0);
         console.log(`First Name: ${prod.FirstName}`);
         return context.executeAction({
             'Name': "/dynamicApp/Actions/gotoOdataPage.action",
             'Properties': {
                 "Message": `First Name: ${prod.FirstName}`
             }
         });
     }
 });

Any suggestion here?

Thanks,

Padmindra

bill_froelich
Product and Topic Expert
Product and Topic Expert

Have you successfully initialized the service before you try to read from it?

Padmindra
Explorer
0 Kudos

Hi Bill,

thanks for your suggestion.

After successfully initialised, the clientApi.read API start working fine.

the entityset data is able to read.

Regards,

Padmindra

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

I'm not quite sure how you are intending consume the result from this call.

MDK provides multiple options for referencing the entity and retrieving the value based on where you are using that in your application. For example, within a rule you can use the clientAPI.read method to return the content of an entity and then within your rule act on the result. You can also setup target binding to the entity to display the result on a page within your application.

joreddy
Explorer
0 Kudos

Hi Bill,

There results from the above api call will be used in the subsequent post calls to the backend.

I've tried using the clientAPI.read method from the method but got an error.

It would be helpful if you could provide a code snippet if available.

Thanks.

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

Here is an example rule using context.read

export default function CheckForProductScanMatch(pageProxy) {
	pageProxy.dismissActivityIndicator();
	var actionResult = pageProxy.getActionResult('BarcodeScanner');
	if (actionResult) {
  		const scanValue = actionResult.data;
	  	// Check if the scan value matches a Product ID
	  	return pageProxy.read('/demoApp/Services/SampleSvc.service', 'Products', [], `$filter=ProductId eq '${scanValue}'`).then(function(result) {
	    	if (result && result.length > 0) {
	        	pageProxy.setActionBinding(result.getItem(0));
	        	return pageProxy.executeAction('/demoApp/Actions/Products/ShowProductDetail.action');
			} else {
				// No matching product found.  Display a message to the user
				var message = pageProxy.localizeText('scan_no_match',[scanValue]);
				var title = pageProxy.localizeText('scan_product');
				var okCaption = pageProxy.localizeText('ok');
				pageProxy.setActionBinding({
    				'Message': message,
    				'Title': title,
    				'OKCaption': okCaption
    			});
        		return pageProxy.executeAction('/demoApp/Actions/Products/ProductScanNoMatchFound.action');
	    	}
    	});
  	} 
}

joreddy
Explorer
0 Kudos

Hi Bill,

Thanks for the source code.

I've tried this earlier as well but unfortunately the filter is not working on the service.

And also for few other calls I need to make a PATCH call to update a particular instance of the entity.

It would be helpful if something like below possible.

scanValue = 1234
pageProxy.read('/demoApp/Services/SampleSvc.service', "Products('${scanValue}')", []) // GET/PATCH/PUT/POST

Thanks.

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

The read can support directly referencing the entity id like in your example rather than using a filter,

You may want to investigate the send request method as it seems like your service may not be fully odata compliant.

bill_froelich
Product and Topic Expert
Product and Topic Expert
0 Kudos

To use the ${scanValue} syntax you need to make sure your string is using back ticks instead of double quotes.

scanValue = 1234
pageProxy.read('/demoApp/Services/SampleSvc.service', `Products('${scanValue}')`, [])
joreddy
Explorer
0 Kudos

Hi Bill,

Any entity if I call from the rule it gives below error.

Error: Could not find the service provider

But same service on table binding works fine.

export default function UserDetails(clientAPI) {
var user = "1042130"; alert(user); return clientAPI.read('/GoodsReceiptApplication/Services/cwfeccgw.service', `ZGR_GET_USERDETAIL('${user}')`, []).then(function (result) { // return clientAPI.read('/GoodsReceiptApplication/Services/cwfeccgw.service', "ZGR_POHEADERSet", []).then(function (result) { return JSON.stringify(result);
}).catch(function(err){ alert(err); return err; });
}
learner1
Explorer
0 Kudos
Hi joreddy, were you able to resolve the error 'Could not find the service provider' when directly calling from the Rule? I am also getting the same error when the rule is bind to list picker to read the data. Same works when entity is bind to the list picker.