How to update the value of a single datapoint using https - https

While the Xively API documentation and Libraries provide a good resource to read and write to Xively feeds and datastreams I cant seem to find a reference how to compose a https request to update a single datapoint.
For Example: To code a "button" on a web page that can change the value of a data point from 1 to 0, which triggers an action on the device that is connected to/with this Feed. i.e to compose a request directly in a browser to obtain the desired effect..
I am very new to this and any guidance to this would be appreciated.

You should use XivelyJS.
There is a full example of a webpage which uses WebSockets.
It's very easy to use.
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/xively-js/1.0.4/xivelyjs.min.js"></script>
<script>
// Set your API key first
xively.setKey( "YOUR_KEY_HERE" );
xively.datastream.update( "YOUR_FEED_ID", "test_datastream", 123, function( event, data ) {
console.log( data.current_value ); // Logs value changes in realtime
});
</script>

Related

How to fetch data before component mount in Svelte?

Unlike onMount there is no beforeMount lifecycle event in SvelteJS. So, how do we fetch data that the page depends on before mounting? onMount fetches produces glitches. One can say that I can wrap dependent DOM inside if conditions. But I don't think it is the right solution. Very like in Sapper there is a preload function that can load page dependent data before mounting. What is the alternative to this (Sapper's preload) behavior in SvelteJS?
You'd create another component that doesn't render the Component until the data is ready.
<script>
import Post from "./Post.svelte";
const url = 'https://jsonplaceholder.typicode.com/posts/1';
const promise = fetch(url).then(response => response.json());
</script>
{#await promise then data}
<Post title={data.title} />
{/await}
REPL
Depending on the scenario you can use a router that has data loading supports, like the sveltekit router.
You can put the fetch code right under <script> tag
A <script> block contains JavaScript that runs when a component instance is created.
There is also context="module" attribute with <script> tag. It
runs once when the module first evaluates, rather than for each component instance
See the official docs
Noob here, to your sub-question: isnt svelte front end only? Meaning no SSR support and thus no option for preloading data with first user request.
Since, you dont have any server that would preload your data and give the user prepacked front-end (svelte pages) with data. Thus, you need sapper to provide a functionality where server can fetch data with first user request, populate front end and send it to user.. This way, user receives svelte pages, populated with data, upon first response from your server.
Since you use only svelte, user needs to contact your server more often.. First, it fetches the front-end, then front-end fetches data from back-end. Furthermore, it aint SEO friendly as robots dont wait for the subsequent server responses. Thus, your pages wont be analyzed properly as robots analyze 'blank'page, no data mounted yet, and move to next, before response can be processed.
Please, correct me If I am wrong ;)
I believe above answer is right:
1. create empty variable in script tag
2. add below onMount call and fetch data from serverto above declared variable
3. check if var is empty and show loading button
4. if var isnt empty, then show user content
6. profit?
P.S: Sorry for any misconceptions or bad English :)

How to use NodeJS with node-rest-client methods to post dynamic data to front end HTML

I am rather new to NodeJS so hopefully I am able to articulate my question(s) properly. My goal is to create a NodeJS application that will use the node-rest-client to GET data and asynchronously display it in HTML on client side.
I have several node-rest-client methods created and currently I am calling my GET data operation when a user navigates to the /getdata page. The response is successfully logged to the console but I'm stumbling on the best method to dynamically populate this data in an HTML table on the /getdata page itself. I'd like to follow Node best practices, ensure durability under high user load and ultimately make sure I'm not coding a piece of junk.
How can I bind data returned from my Express routes to the HTML front end?
Should I use separate "router.get" routes for each node-rest-method?
How can I bind a GET request to a button and have it GET new data when clicked?
Should I consider using socket.io, angularjs and ajax to pipe data from the server side to client side?
-Thank you for reading.
This is an example of the route that is currently rendering the getdata page as well as calling my getDomains node-rest-client method. The page is rendering correct and the data returned by getDomains is successfully printed to the console, however I'm having trouble getting the data piped to the /getdata page.
router.get('/getdata', function(req, res) {
res.render('getdata', {title: 'This is the get data page'});
console.log("Rendering:: Starting post requirement");
args = {
headers:{"Cookie":req.session.qcsession,"Accept":"application/xml"},
};
qcclient.methods.getDomains(args, function(data, response){
var theProjectsSTRING = JSON.stringify(data);
var theProjectsJSON = JSON.parse(theProjectsSTRING);
console.log('Processing JSON.Stringify on DATA');
console.log(theProjectsSTRING);
console.log('Processing JSON.Parse on theProjectsSTRING');
console.log('');
console.log('Parsing the array ' + theProjectsJSON.Domains.Domain[0].$.Name );
});
});
I've started to experiment with creating several routes for my different node-rest-client methods that will use res.send to return the data and the perhaps I could bind an AJAX call or use angularjs to parse the data and display it to the user.
router.get('/domaindata', function(req, res){
var theProjectsSTRING;
var theProjectsJSON;
args = {
headers:{"Cookie": req.session.qcsession,"Accept":"application/xml"},
};
qcclient.methods.getDomains(args, function(data, response){
//console.log(data);
theProjectsSTRING = JSON.stringify(data);
theProjectsJSON = JSON.parse(theProjectsSTRING);
console.log('Processing JSON.Stringify on DATA');
console.log(theProjectsSTRING);
console.log('Processing JSON.Parse on theProjectsSTRING');
console.log('');
console.log('Parsing the array ' + theProjectsJSON.Domains.Domain[0].$.Name );
res.send(theProjectsSTRING);
});
});
I looked into your code. You are using res.render(..) and res.send(..). First of all you should understand the basic request-response cycle. Request object gives us the values passed from routes, and response will return values back after doing some kind of processing on request values. More particularly in express you will be using req.params and req.body if values are passed through the body of html.
So all response related statements(res.send(..),res.json(..), res.jsonp(..), res.render(..)) should be at the end of your function(req,res){...} where you have no other processing left to be done, otherwise you will get errors.
As per the modern web application development practices in javascript, frameworks such as Ruby on Rails, ExpressJS, Django, Play etc they all work as REST engine and front end routing logic is written in javascript. If you are using AngularJS then ngRoute and open source ui-router makes work really easy. If you look closely into some of the popular MEAN seed projects such as mean.io, mean.js even they use the ExpressJS as REST engine and AngularJS does the rest of heavyweight job in front end.
Very often you will be sending JSON data from backend so for that you can use res.json(..). To consume the data from your endpoints you can use angularjs ngResource service.
Let's take a simplest case, you have a GET /domaindata end point :
router.get('/domaindata',function(req,res){
..
..
res.json({somekey:'somevalue'});
});
In the front end you can access this using angularJS ngResource service :
var MyResource = $resource('/domaindata');
MyResource.query(function(results){
$scope.myValue = results;
//myValue variable is now bonded to the view.
});
I would suggest you to have a look into the ui-router for ui front end routing.
If you are looking for sample implementation then you can look into this project which i wrote sometime back, it can also give you an overview of implementing login, session management using JSON Web Token.
There are lot of things to understand, let me know if you need help in anything.

Meteor: Uploading an image and saving to the database as base64 string

I have a Meteor app and I am interested in getting image upload to work in the simplest possible manner.
The simplest manner I can come up with is to somehow convert the image to a base64 string on the client and the save it to the database as a string.
How is it possible to convert an image on the users filesystem to a base64 string and then save it to the database?
You can use an HTML5 file input :
HTML
<template name="fileUpload">
<form>
<input type="file" name="imageFile">
<button type="submit" disabled={{submitDisabled}}>
Submit
</button>
</form>
</template>
Then listen to the change event and use a FileReader to read the local file as a base64 data url that we're going to store in a reactive var :
Template.fileUpload.created=function(){
this.dataUrl=new ReactiveVar();
};
Template.fileUpload.events({
"change input[type='file']":function(event,template){
var files=event.target.files;
if(files.length===0){
return;
}
var file=files[0];
//
var fileReader=new FileReader();
fileReader.onload=function(event){
var dataUrl=event.target.result;
template.dataUrl.set(dataUrl);
});
fileReader.readAsDataURL(file);
}
});
Then we can use the reactive var value to allow/disallow form submission and send the value to the server :
Template.fileUpload.helpers({
submitDisabled:function(){
return Template.instance().dataUrl.get();
}
});
Template.fileUpload.events({
"submit":function(event,template){
event.preventDefault();
//
Meteor.call("uploadImage",template.dataUrl.get());
}
});
You will need to define a server method that saves the dataUrl to some collection field value, what's cool about dataUrls is that you can use them directly as an image tag src.
Note that this solution is highly unscalable as the image data won't be cachable and will pollute the app database regular communications (which should only contain text-like values).
You could fetch the base64 data from the dataUrl and upload it to Google Cloud Storage or Amazon S3 and serve the files behind a CDN.
You could also use services that do all of this stuff for you like uploadcare or filepicker.
EDIT :
This solution is easy to implement but comes with the main drawback that fetching large base64 strings from mongodb will slow your app from fetching other data, DDP communications are always live and not cachable at the moment so your app will always redownload image data from the server.
You wouldn't save dataUrls to Amazon, you would save the image directly, and it would be fetched by your app using an Amazon URL with a cachable HTTP request.
You have two choices when it comes to file upload : you can upload them directly from the client using specific javascript browser APIs or you can upload them within Node.js (NPM modules) APIs in the server.
In the case you want to upload from the server (which is usually simpler because you don't need to require that the users of your apps authenticate against third party services, only your server will act as a trusted client to communicate with Amazon API), then you can send the data that a user want to upload through a method call with a dataUrl as argument.
If you don't want to dive into all this stuff consider using uploadcare or filepicker, but keep in mind that these are paid services (as is Amazon S3 BTW).
Not sure if this is the best way, but you can easily do this with a file reader. In the Template event handler where you get the file contents, you can pass the file to the reader and get back a base64 string. For example, something like this:
Template.example.events({
'submit form': function (event, template) {
var reader = new FileReader();
var file = template.find('#fileUpload').files[0]; // get the file
reader.onload = function (event) {
// event.target.result is the base64 string
}
reader.readAsDataURL(file);
}
});

ajax form submit cross server

I have several servers on an intranet. I am passing data from one server to be processed on another server. Attempting to use ajax but I am a noob.
<script type="text/javascript" src="jquery-1.8.0.js"></script>
<script type="text/javascript">
function print(oForm){
var toggle = oForm.elements["toggle"].value;
var ticket_type_id = oForm.elements["ticket_type_id"].value;
var printer_id = oForm.elements["printer_id"].value;
var store_id = oForm.elements["store_id"].value;
var data = oForm.elements["data"].value;
var dataString = "toggle="+ toggle+ "&ticket_type_id="+ ticket_type_id+ "&printer_id="+ printer_id+ "&store_id="+ store_id+ "&data="+ data;
$.ajax(
{
type:"POST",
url:"http://192.168.12.103/crowncontrol/backend/processes/print.php",
data:dataString,
success: function(data){
alert("successful");
}
}
);
}
</script>
The above URL does not work.
But if I make the url:
"../../../backend/processes/print.php"
Which is the same location, it works fine.
Also if I send it via Anchor Get it works fine:
href="http://192.168.12.103/crowncontrol/backend/processes/print.php?etc"
The reason I am using ajax is, I want my print.php script to run with out the user noticing. The reason I can't use url:"../../../backend/processes/print.php" is because I will be sending information from one server to another servers on my intranet.
Any help would be appreciated. I've spent far too long trying to get it to work on my own.
AFTER help from the answers below instead of the entire ajax code I used:
$.getJSON('http://192.168.12.103/crowncontrol/backend/processes/print.php?callback=?',dataString,function(res){
//alert('Success');
});
also:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript">
This is a result of the same origin policy. You can not perform a normal AJAX requests cross-domain requests for security reasons (see the link about same origin policy).
Fortunately for you jQuery includes JSONP request support which uses script tag injection instead of XMLHttpRequest.
Instead of creating and using an xhr object (XMLHttpRequest which is how ajax is done) it creates a script tag with an src attribute set to your URL. it should work.
Try changing your code to :
$.ajax(
{
type:"POST",
url:"http://192.168.12.103/crowncontrol/backend/processes/print.php?callback=?",
data:dataString,
success: function(data){
alert("successful");
}
}
);
(notice the ?callback=? part)
Here is a jsonp tutorial for jQuery
Here is some information about jsonp and some information about the same origin policy
Easy way to deal with this problem is to make a script file in your server and then route the requests through that server request.Use this logic below:
Instead of making the AJAX request directly to cross domain, make the AJAX request to a new script on your server.
In that script file, get the request and make the required call(to that cross domain address).
Then recieve the response from the cross domain server and send it to the client.
Receive the result from your own server which has required data.
This diagram shows:

ASP.NET 4.0 routing + ajax + browser history

The problem with ASP.NET 4.0 routing is that the Page.RouteData.Values does not contain the paramenters after # character from the link
System.Web.Routing.RouteTable.Routes.MapPageRoute("ProjectViewRoute1",
"project/{title}/{idProject}#{idDesign}", "~/ProjectView.aspx");
As I said, the Page.RouteData.Values.ContainsKey("idDesign") will return false
The reason I want to make use of this feature is because I use JavaScript and Ajax to hide some content and load new one, wich in eyes of an user is like loading a different page, and he must be able to copy paste the URL and view that page later.
The question is: how to get the {idDesign} from the RoutedData ?
Browsers don't send data after the # in the URLs to the server; as a result, it is not possible for ASP.Net to capture that data and provide it to you.
I would recommend using a ? instead of your # to get the functionality you need, and include an AJAX call to capture data placed in the hash section of the url to send to the server, if necessary, for AJAX-created urls.
Using jQuery:
$(function () {
if (location.hash) {
hash = location.hash.substr(1);
location.hash = null;
location.search = hash;
}
});

Resources