I'm trying to develop a mobile app that will integrate with Sharepoint 2010 so that my clients can make approvals and stuff from a mobile device. (I'm hoping to build a HTML5/Android Native app that will call webservices and get the job done)
I looked it up and there is a RESTful API for Sharepoint that I think I can use with the ECMAScript library. Can I use this same REST API to view pending approvals, to approve/reject, etc or is the functionality limited to viewing data?
Sorry but i'm a newbie to Sharpoint. Could someone throw a little light on whether I have the right idea?
Thanks
For my needs I am using custom SOAP Web Services to do what I want in SharePoint side. Unfortunately, I have no experience with the built-in services, may be it is enough for your needs, but I don't think so. But you can start your investigation here:
http://msdn.microsoft.com/en-us/library/ff521587.aspx
http://msdn.microsoft.com/en-us/library/ee705814.aspx
Creation of custom Web Services is simple and it can give you great possibilities.
On the mobile part I am using Cordova (PhoneGap) to create mobile application (based on Html+JS). For WebService invokation I am using code like this:
var url=server+"/_layouts/CustomWebServices/MyCustomWebService.asmx";
var req = createXMLHTTPObject();
req.onreadystatechange= function(){
if(req.readyState != 4) return;
if(req.status != 200) {
if (onerror)
onerror('status: '+req.status+req.responseCode+req.responseText);
return;
}
callback();
};
var soapBodyDoc=mkXML(soapBody);
req.open("POST",url,true);
req.setRequestHeader('SOAPAction', 'http://mysite/'+soapAction);
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
req.setRequestHeader('Authorization', 'Basic '+auth);
req.setRequestHeader('Expect', '100-continue');
req.setRequestHeader('Connection', 'Keep-Alive');
req.send(soapBodyDoc);
As you can see I am using Basic authorization. Maybe it is not the best approach, but I am a newbie too :). I can't remember for the moment, what I exactly did to allow Basic authentication, but if you couldn't find this information let me know, I'll try to remember.
To create UI you can use jQuery mobile. It is very useful.
If you have additional questions - let me know.
Related
I have a simple website that's hosted on an Azure Web App that's literally just one .html file, one .css file, and one .js file. It uses the Bing API to get data and chartjs to graph that data on the page.
The issue is I obviously don't want to store the API key in the code anywhere anyone else can find it, so I'm not sure where to put it. I tried setting up an Azure Key Vault and adding the API Key as a secret, so I could just do a REST GET and retrieve the key, but I'm not sure how to setup permissions to allow the server the Web app is on (and only that server) to access it.
The more I research do and reading other similar questions the more I feel like this isn't the best solution out there (couldn't anyone just intercept the response in plain text?), but I'm yet to find a "best practice" for this problem. Any alternative solutions or advice on how to make this work are welcome.
EDIT: The more I'm thinking about this the more I realize using the Key Vault won't work. There is no server side to this application, so the request for the API key will come from any IP. I'm thinking I'm going to have add a whole server side application for this to work. Just to give you an idea of what I've got going on so far here's some pseudo code.
----------index.html----------
<head>
<script src = "./chart.js"></script>
</head>
<body>
<canvas id="mainChart" width="400" height="400"></canvas>
<script src="./app.js"></script>
</body>
----------app.js----------
var BING_API_KEY = "myprivatebingapikey";
var CLIENT_ID = "bingapikeyclientid";
function getData() {
return new Promise(resolve => {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://api.cognitive.microsoft.com/bing/v7.0/myquery", true);
xhttp.setRequestHeader("Ocp-Apim-Subscription-Key", BING_API_KEY);
xhttp.setRequestHeader("Accept", "application/json");
xhttp.setRequestHeader("X-MSEdge-ClientID", CLIENT_ID);
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = JSON.parse(xhttp.responseText);
if (!response.value || response.value.length <= 0) {
throw Error;
}
resolve(parseData(response.value));
}
}
xhttp.send(null);
});
}
function parseData(data) {
// put the data into global variables
}
function graphData() {
await getData();
var chart = new Chart(document.getElementById('mainChart'),
data: { // all the data from the global variables },
labels: { // labels from global variables },
options: { // predefined options }
}
graphData();
The code isn't perfect, but it's just to give you an idea about how it's set up.
It looks like you have realised you will need some kind of server side code to keep your secrets secret. Even if you store your secret in a Key Vault that won't help, anyone could just open a web debugger (F12) and see the secret in plain text.
I would suggest an Azure Function with something like an HTTP trigger. This will enable you to build a very light weight server side web service. Put all your getData() code into the Azure Function (you can provide the implementation in JavaScript), along with your secrets. Call the Azure Function in your JavaScript client side to get the data you need for the chart.
An introduction to Azure Functions
Azure Functions is a solution for easily running small pieces of code,
or "functions," in the cloud. You can write just the code you need for
the problem at hand, without worrying about a whole application or the
infrastructure to run it. Functions can make development even more
productive, and you can use your development language of choice, such
as C#, F#, Node.js, Java, or PHP. Pay only for the time your code runs
and trust Azure to scale as needed. Azure Functions lets you develop
serverless applications on Microsoft Azure.
I just read this post, and I do understand what the difference is. But still in my head I have the question. Can/Should I use it in the same App/Website? Say I want the AngularJs to fetch content and update my page, connecting to a REST api and all of that top stuff. But on top of that I also want a realtime chat, or to trigger events on other clients when there is an update or a message received.
Does Angular support that? Or I need to use something like Socket.io to trigger those events? Does it make sense to use both?
If someone could help me or point me to some good reading about that if there is a purpose for using both of them together.
Hope I'm clear enough. thank you for any help.
Javascript supports WebSocket, so you don't need an additional client side framework to use it. Please take a look at this $connection service declared in this WebSocket based AngularJS application.
Basically you can listen for messages:
$connection.listen(function (msg) { return msg.type == "CreatedTerminalEvent"; },
function (msg) {
addTerminal(msg);
$scope.$$phase || $scope.$apply();
});
Listen once (great for request/response):
$connection.listenOnce(function (data) {
return data.correlationId && data.correlationId == crrId;
}).then(function (data) {
$rootScope.addAlert({ msg: "Console " + data.terminalType + " created", type: "success" });
});
And send messages:
$connection.send({
type: "TerminalInputRequest",
input: cmd,
terminalId: $scope.terminalId,
correlationId: $connection.nextCorrelationId()
});
Usually, since a WebSocket connection is bidirectional and has a good support, you can also use it for getting data from the server in request/response model. You can have the two models:
Publisher/Subscriber: Where the client declares its interest in some topics and set handlers for messages with that topic, and then the server publish (or push) messages whenever it sees fit.
Request/response: Where the client sends a message with a requestID (or correlationId), and listen for a single response for that requestId.
Still, you can have both if you want, and use REST for getting data, and WebSocket for getting updates.
In server side, you may need to use Socket.io or whatever server side framework in order to have a backend with WebSocket support.
As noted in the answer in your linked post, Angular does not currently have built-in support for Websockets. So, you would need to directly use the Websockets API, or use an additional library like Socket.io.
However, to answer your question of if you should use both a REST api and Websockets in a single Angular application, there is no reason you can't have both standard XmlHttpRequest requests for interacting with a REST api, using $http or another data layer library such as BreezeJS, for certain functionality included in various parts of the application and also use Wesockets for another part (e.g. real time chat).
Angular is designed to assist with handling this type of scenario. A typical solution to would be to create one or more controllers to handle the application functionality and update your page and then creating separate Services or Factories that encapsulate the data management of each of your data end points (i.e. the REST api and the realtime chat server), which are then injected into the Controllers.
There is a great deal of information available on using angular services/factories for managing data connections. If you're looking for a resource to help guide you on how to build an Angular application and where data services would fit in, I would recommend checking out John Papa's AngularJS Styleguide, which includes a section on Data Services.
For more information about factories and services, you can check out AngularJS : When to use service instead of factory
I'm building a mobile app using OpenUI5 and Cordova. This app consume OData services but must support full offline capabilities. There are many optiones to store data using Cordova such as LocalStorage, Web SQL or even FileWriter. Also I find that OpenUI5 framework offer jQuery.sap.storage to store data through LocalStorage but I can't take this option into account due to the limited storage capacity (5MB).
Is it possible to request the entire data model from the OData service and convert it into JSON model? Because if there is any way to accomplish this, I could write files for every entity in the model (and the metadata file) using the FileWriter and consume this model when the app goes offline.
Does anyone tried to do something like this?
Edited
Thanks for answering...
I'm using jumpifzero tips to set data from the OData services into the Json model, like this:
var sServiceUrl = "http://address:port/DataService.svc/";
var odataModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true);
var jsonModel = new sap.ui.model.json.JSONModel();
odataModel.read("/Dates", {
async: false,
success: function (odata, response) {
jsonModel.setData({ Dates: odata.results });
}
});
this.setModel(jsonModel);
You can also read the odata for each entityset, with the .read method, without any filter. In the success function given to the read, you can put the JS objects in a JSON model.
You can make a layer that fills the JSON model from the odata when online and from localstorage when offline.
You have an option to create offline apps (CRUD) using offline Kapsel plugin (Cordova plugin developed by SAP) that comes with SAP Mobile Platform. You should buy license for SAP Mobile Platform.
You can find more information here: http://scn.sap.com/docs/DOC-58063
I don't suggest offline Kapsel plugin. It is not mature enough to use it and it is actually under development. Furthermore you would need an SMP server for offline feature.
I would rather say you should use a half-baked solution that you form according your needs e.g.: http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/
Is it possible to upload a file to Office 365 OneDrive Business (SharePoint), using pure JavaScript or jQuery, when running from an external website? (Not a SharePoint site)
I have written some C# code, which authenticates a user, and gets a FormDigestValue. But I don't know where to go from there.
None of the examples I found, seems to work for me.
you can always use the Office365 REST API to access OneDrive Business. This works well with JavaScript, especially using jQuery or AngularJS since they are more easy to use refering to REST.
You will find some examples here:
http://blogs.msdn.com/b/sharepointdev/archive/2013/08/13/access-skydrive-pro-using-the-sharepoint-2013-apis.aspx
Have you checked the new JS library for O365 APIs, including OneDrive Business service?
It should support CORS.
Yes, it is, I am doing it and it works great..
0) Please, have a look here first, it's a great study and helps to understand CORS:
https://msdn.microsoft.com/en-us/office/office365/howto/create-web-apps-using-cors-to-access-files-in-office-365
1) Register your app (www.yourdomain.name) in Azure AD (Active Directory) - you must have Office 365 and Azure AD subscription - make sure you change the manifest in Azure AD and set OAuth Implicit = Yes This allows you to get across
2) make sure you're able to receive oAuth token on your site which is registered in Azure AD - again (your.domain.name)
3) Then you AJAX (http://www.yourdomain.name) should have something like this:
xhr.open("PUT", OneDriveForBusinessEndPointURL, true);
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("Content-Type", fileInput.files[0].type);
xhr.send(fileInput.files[0]);
var FileName = fileInput.files[0];
//// Your Endpoint should be like this
var OneDriveForBusinessEndPointURl = https://mydomain-mysharepoint.com/_api/v2.0/drives/{drive-id}/items/{folder-id}:/FileName:/content
Once you get JSON with xhr.status = 201 or 200, you've won.
I am working on html & js in which i display yahoo finance stock in table format. The data get in csv. I want js directly read data from url
The url is http://ichart.finance.yahoo.com/table.csv?s=RIL.BO
The code i try which i get from stackoverflow is working in localhost url.
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "http://ichart.finance.yahoo.com/table.csv?s=RIL.BO", true);
txtFile.onreadystatechange = function() {
if (txtFile.readyState === 4) { // Makes sure the document is ready to parse.
if (txtFile.status === 200) { // Makes sure it's found the file.
allText = txtFile.responseText;
lines = txtFile.responseText.split("\n"); // Will separate each line into an array
alert(allText);
}
}
}
Thanks
In order to get around the Cross Domain request restrictions put in place by the Same Origin Policy, you need an endpoint that allows you to do a JSONP request or that has enabled CORS. Unfortunately, the Yahoo! Finance endpoint has neither.
So, as James mentioned, you ned a middle man.
Usually, my recommendation for this is to use YQL, which allows you to quickly and easily build a server that sits between you and the finance site. In fact, they already have a Yahoo! Finance endpoint for exactly the data you're trying to get: link
However, as that can be unreliable, I also have a website scraper that I've used in various projects. It's hosted on Heroku and allows you to fetch almost any content from any site. I don't recommend using it for high volume projects, but for occaisional data fetches it's great. In your case, you would use it like this:
http://websitescraper.herokuapp.com/?url=http://ichart.finance.yahoo.com/table.csv?s=RIL.BO&callback=jsCallback
Edit: ichart.finance.yahoo.com has been deprecated, so this fails. Keeping it here for reference
Now that you have that out of the way, I recommend using jQuery and the csv-to-array plugin:
jQuery.getJSON('http://websitescraper.herokuapp.com/?url=http://ichart.finance.yahoo.com/table.csv?s=RIL.BO&callback=?', function (csvdata) {
console.log(csvdata.csvToArray());
});
Also, if you want to launch your own middle man, you can use the website-scraper that I've built. The source code is on GitHub and it's released under the MIT license.
You are trying to do a cross domain request so its being blocked.
You will need to write a server side script to fetch the data for you.