Cloudkit JS && Node JS - javascript

I'm currently trying to perform server side connection to iCloud Server using the new CloudKit JS from Apple. According to the WWDC 2015 "CloudKit JS and Web Service", since CloudKit JS is a pure JS framework, you can use it in all JS environnements such as node JS.
I copied the source code of CloudKit JS from https://cdn.apple-cloudkit.com/ck/1/cloudkit.js and pasted it in a file named "cloudkit.js". Here is a demo of what I tried :
var CloudKit = require("/some/folders/cloudkit.js")
function demoPerformQuery() {
CloudKit.configure({
containers: [{
containerIdentifier: 'myContainerIdentifier',
apiToken: 'myAPIToken',
environment: 'development'
}]
})
var container = CloudKit.getDefaultContainer();
var publicDB = container.publicCloudDatabase;
publicDB.performQuery({recordType: 'Items'}).then(function(response){
// never called :-(
})
}
var express = require('express')
var app = express()
app.get("/", function(){
demoPerformQuery()
})
var server = app.listen(8080, function () {
console.log("server launched")
})
CloudKit seems to be correctly set up since all the functions are correctly called. But the callback of performQuery is never called. Why ?
Is there someone who already succeed to configure CloudKit JS in an server environnement ?
Thanks in advance

In the browser, CloudKit.js relies on XmlHttpRequest in order to fetch resources, but since CloudKit isn't an npm module you'll need a way to fetch things from your server.
npm install node-fetch
Using node-fetch, here is a tweaked version of your code that logs the resulting Items in your query:
var fetch = require('node-fetch');
var CloudKit = require("./cloudkit.js")
CloudKit.configure({
services: {
fetch: fetch
},
containers: [{
containerIdentifier: 'yourContainerIdentifier',
apiToken: 'yourAPItoken',
environment: 'development'
}]
})
var container = CloudKit.getDefaultContainer();
var publicDB = container.publicCloudDatabase;
function demoPerformQuery() {
publicDB.performQuery({recordType: 'Items'}).then(function(response){
console.log(response)
}).catch(function(error){
console.log(error)
})
}
var express = require('express')
var app = express()
app.get("/", function() {
demoPerformQuery()
})
var server = app.listen(8080, function () {
console.log("Server listen")
})
After hitting http://localhost:8080 you should see your server log the response to your query.

Related

How to send data from react to nodejs without localhost?

I am trying to deploy reactjs & nodejs app to heroku.
I have successfully deployed frontend,but frontend is sending data to nodejs using localhost due to which when running app through heroku only frontend is working.
This code send data to nodejs.
saveUserJson = (User) =>{
const url = 'http://localhost:5000/write'
axios.post(url,User)
.then(response => {
//console.log(response);
});
}
This is nodejs code(ignore hostname in code).
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const morgan = require('morgan');
const cors = require('cors');
const jsonData = require('../src/descriptors/bnk48.json')
const app = express();
const port = 5000;
const hostname = '192.168.43.113';
app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cors());
app.get('/',(req,res) => res.status(200).send({
message: "Server is running..."
}));
const WriteTextToFileSync = (contentToWrite) => {
fs.writeFileSync('./src/descriptors/bnk48.json',contentToWrite,(err) =>{
//console.log(contentToWrite);
if(err) {
console.log(err);
}else {
console.log('Done writing to file successfully...')
}
})
}
const user = {
}
app.post('/write',(req,res,next) =>{
const user = {
"name": req.body[0].name,
"descriptors": req.body[0].descriptors
}
jsonData[user.name]=user
//console.log(req.body[0].descriptors)
const requestContent = JSON.stringify(jsonData,null,2);
WriteTextToFileSync(requestContent)
});
app.use((req,res,next) => res.status(404).send({
message: "Couldn't find specified route that was requested..."
}));
app.listen(port,hostname,()=>{
console.log(
`
!!! server is running..
!!! Listening for incoming requests on port ${port}
!!! Server running at http://${hostname}:${port}/
!!! http://localhost:5000
`
)
})
How can i change localhost so that while deploying it automatically chooses where to send data?
How can i change localhost so that while deploying it automatically chooses where to send data?
There are several ways to do this, but it's quite common to use environment variables for this purpose. These are set by environment, your development machine being one environment and your production site on Heroku being another environment. You could for example define the environment variable BACKEND_ROOT_URL to hold the schema and FQDN of your site, and make your axios call like this:
saveUserJson = (User) =>{
const url = `${process.env.BACKEND_ROOT_URL}/write`
axios.post(url,User)
.then(response => {
//console.log(response);
});
}
The build-time value of url will be different, depending on which environment you perform the build in.
Setting environment variables locally can be done in several ways. In a Bash shell you can set them manually like export BACKEND_ROOT_URL=http://localhost:5000. That get's boring quite fast though, so I would recommend you to check out dotenv which handles this for you efficiently.
Heroku has its own way of handling the setting of envvars - check the documentation here

Error with Cheerio on Node js

i'm trying to parse code with cheerio and request on Node Js, and i'm getting error undefinedi've been checked this, that's not request error it's cheerio
here part of my parse code.
const options = Object.assign({
url: buildUrl(opts),
followAllRedirects: true
}, opts.requestOptions);
request(options, opts.throttle)
.then(cheerio.load)
.then(parseFields)
.then(function (app) {
resolve(app);
})
.catch(reject);
});
}
function parseFields ($) {
const h2 = $('faq_cat').attr('id')
const fields = {
h2
};
what i'm trying to parse
<div class="faq_cat" id="faq_box_faq2">
Thanks everybody !)
Express server app code :
const express = require('express')
const app = express()
var gplay = require('google-play-scraper');
gplay.download({downloadId: 'air.com.helloair.HELLOFROG',
nameid: 'digital-world-digimons'})
.then(console.log, console.log);
app.listen(3000, () => console.log('Example app listening on port 3000!'))
with console.log(h2)
code screen
with console.log($.html());
screen work!
Your selector is missing a .
Right now you are looking for a tag called faq_cat, which does not exist. You want to select a element with the class name faq_cat
Use const h2 = $('.faq_cat').attr('id')

Connect Nodejs and Angular 2 to SQL Server 2014

I am using Angular 2 and Nodejs to Connect to an SQL Server. If I simply put following code in a js file and run it through the console using node test.js the code deletes the record properly.
Here is the code:
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
After that I moved the same file to the src folder in my Angular 2 project (where the index.html file also exists). I put the same code into a function in test.js file like that:
function testConnection()
{
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
}
Now I want to call testConnection() from the index page. I have put the <script src="C:\Users\amandeep.singh\Desktop\Angular\my-app\src\test.js"> to script path and call the function using this:
<script>
testConnection();
</script>
The index page executes properly but doesn't show any error nor executes the command. I'm unable to understand why the same code works in the console on Nodejs but not in my index.html.
Help will be appreciated.
You can't run Node applications in the browser. Nodejs is an application that runs Javascript in Google's V8 Javascript VM on your operating system and is meant to be a backend system (at least in the web development stack).
So you basically have to run your Node program on a webserver and make your API requests from the Angular application.
There are several tutorials out there on the internet that help you with this.
Here is the official Angular documentation angular.io

Why am I failing to get data from the server using angularjs $http.get()?

The question should be clear enough, and my code should display the issue. Any questions just comment underneath.
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
var characters = {"Griffins":
[{"Name":"Lois Griffin",
"Gender":"Female",
"Role": "Mother"},
{"Name":"Chris Griffin",
"Gender":"Male",
"Role": "Son"},
{"Name":"Meg Griffin",
"Gender":"Female",
"Role": "Daughter"}]
};
app.get("/characters", function(req, res) {
res.send(characters);
})
app.listen(9000, function(){
console.log('Running');
});
angular.js
app.controller('listCtrl',function($scope, $http){
$scope.characterData = function() {
$http.get("/characters").then(function(data) {
console.log(data, 'success')
},function(data) {
console.log("data, failure.")
})
}
})
error
Failed to load resource: the server responded with a status of 404 (
Object "failure."
object in error
Object -
config : Object
data : "Cannot GET /characters↵"
headers : function (d)
status : 404
statusText : "Not Found"
__proto__ : Object
Note: When using $http.get('characters.json')... I am able to get the data from a file called 'character.json'.
404 is a code which the server sends, when the server is not able to find a resource. There can be many reasons that lead to a 404 in response but the most common one's are:
wrong path given.
spelling problem in the path.
$http.get(url, [config]) : There are 2 arguments that are accepted. url is a absolute/relative path. This is a reason why, $http.get('characters.json') is working instead of $http.get('/characters').
So, you should instead use the proper path. If, 'characters.json' is inside '\characters' directory, you should give the correct path $http.get('\characters\characters.json') so that the server can locate the file.
And also, since you are sending json data, you should use, res.json instead of res.send.
The get method in angular need the full url string, probably is something like this:
app.controller('listCtrl',function($scope, $http){
var serverHost = 'example.com';
var serverPort = '9000';
$scope.characterData = function() {
$http.get("http://'+serverHost+':'+serverPort+'/characters").then(function(data) {
console.log("success");
console.log(data);
},function(data) {
console.log("failure");
console.log(data);
})
}
});
Make characters.json file and change app.get method in app.js
app.get('/characters', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "characters.json", 'utf8', function (err, data) {
data = JSON.parse( data );
console.log( data );
res.end( JSON.stringify(data ));
});
})
//change your server configuration
var server = app.listen(8089, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
You can get Json Data in your html page
My own problem now seems to be working. I don't know what is going on, I think there are stability issues in using an online work space and a virtual machine to run servers, even though there shouldn't be. Thank you for everybody's input, I still managed to pick up some good information.

Changin the base URL of loopback lb-services.js

I´m trying to get a client server and a rest api server to connect. I´m using angular js on frontend and loopback on backend.
on the lb-services.js I changed base url to:
var urlBase = 'http://localhost:3000/api';
My angular js is running on port 4000. But when I make a post to the rest api I get this error on my browser:
XMLHttpRequest cannot load http://localhost:3000/api/People. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4000' is therefore not allowed access. The response had HTTP status code 404.
Is there anyway I can proxy the connection or make both servers work together properly?
This is my gulp/server.js:
'use strict';
var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var proxyMiddleware = require('http-proxy-middleware');
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
var server = {
baseDir: baseDir,
routes: routes
};
/*
* You can add a proxy to your backend by uncommenting the line below.
* You just have to configure a context which will we redirected and the target url.
* Example: $http.get('/users') requests will be automatically proxified.
*
* For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
*/
server.middleware = proxyMiddleware('/api', {
target: 'http://localhost:3000/api',
changeOrigin: true
});
browserSync.instance = browserSync.init({
startPath: '/',
server: server,
browser: browser,
port:4000
});
}
browserSync.use(browserSyncSpa({
selector: '[ng-app]'// Only needed for angular apps
}));
gulp.task('serve', ['watch'], function () {
browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});
gulp.task('serve:dist', ['build'], function () {
browserSyncInit(conf.paths.dist);
});
gulp.task('serve:e2e', ['inject'], function () {
browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
browserSyncInit(conf.paths.dist, []);
});
Is there anyway I can proxy the connection or make both servers work
together properly?
It's surprising that you get this error as loopback enables CORS by default. It would be worth checking out the middleware.json file in your loopback server and see whether cors.params.origin is true. Here is the documentation link for your reference.
I'm not sure how you have changed the urlBase for accessing your rest api. I had done it using the angular module config as described here.
You can add CORS support to your LoopBack API:
https://docs.strongloop.com/display/public/LB/Security+considerations#Securityconsiderations-CORS

Categories