AngularJS + Electron: Save Data to JSON File - javascript

I'm very new to AngularJS and Electron, and i'm currently working on a simple desktop app that reads data from a JSON file and allows the user also update and delete data. I'm also using TaffyDB to query the data. I'm able get data from the JSON file but unable to store it in the JSON file.
What i tried so far was this:
myApp.controller('homeController', ['$scope', '$http', function($scope, $http) {
$scope.saveData = function()
{
var data = $scope.data;
$http.post('/src/db/db.json', data).then(function (response) {
console.log(response);
}, function (response) {
console.log(response);
});
};
}]);
Executing the event on the browser i get the following error:
POST http://127.0.0.1:64262/src/db/db.json 404 (Not Found)
This is normal because we cannot access the user's filesystem from javascript.
When i execute the app as a Electron package, i get the following:
Object {data: Array[2], status: 200, config: Object, statusText: "OK"}
But the file was not modified.
I would like to know if there is any way i can accomplish this using AngularJS and Electron.
Important Note: This app needs to run as a standalone desktop application. In other words, my client doesn't what to install other software or apps to be able to use this application.

You can't write to the file system using HTTP, that's for the web only.
Electron is built on Node.js. So take a look at the Node.js File System module. For example:
fs.writeFile('/src/db/db.json', data, (err) => {
if (err) throw err;
console.log('It\'s saved!');
});

Related

How to use $get request in AngularJS after node fetches the data?

I'm building a web app that is going to use an API to display cards when you hover over card text on the app.
I'm using unirest to make the call to the API on my node express server as follows -
unirest.get("https://omgvamp-hearthstone-v1.p.mashape.com/cards")
.header("X-Mashape-Key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
.end(function (result) {
console.log(result.status, result.headers, result.body);
});
The data returns correctly and is displayed in my git bash console as JSON.
How do I use the Angular $get service to make a call against what node has just pulled? I guess my question is , where is this data pulled to once node gets a handle on it?
From what I understand, I would parse this information, but do I have to send this data to use it in my Angular.js file?
I hope I wrote enough information for an answer.
Thank you
If you want to pass the data to your UI, you need to make it accessible through an endpoint, so you could do something like this in your server (I'm using express for simplicity):
app.get('/my-data-endpoint', (req, res) => {
unirest.get("https://omgvamp-hearthstone-v1.p.mashape.com/cards")
.header("X-Mashape-Key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
.end((result) => {
console.log(result.status, result.headers, result.body);
res.send(result);
});
});
and in your angular controller you can do:
$http.get('/my-data-endpoint')
.then((response) => {
console.log(response);
});
just remember to inject the $http dependency in your controller and you should be able to see the response.

Pass a NodeJS express object to AngularJS 1.6

I have a working NodeJS API using Express. I am confused how to properly pass in a parameter from NodeJS to AngularJS in order to retrieve the data for the page.
Note: My question is an extension (not a repeat) of this question:
How do I pass node.js server variables into my angular/html view?
I have set up two routes, one to render the page and one to return the JSON object based on the Book ID (the unique ID of the entity). When the page loads, Angular uses $http to send a GET request to get the data from a JSON endpoint.
This is working, but I have hard-coded an example Book ID in Angular.
Question: How can I pass the Book ID to the Angular controller?
/*EXPRESS ROUTES*/
//Render page
router
.route('/detail/:book_id')
.get(ctrlRequest.detailPage);
//Return JSON data
router
.route('/detail/json/:book_id')
.get(ctrlRequest.detailJSON);
/*NODEJS CONTROLLERS*/
//Render page
module.exports.detailPage = function(req, res) {
res.render('transfer_request_detail.pug', {
title: 'Transfer Request Detail'
});
};
//Return JSON data
module.exports.detailJSON = function(req, res) {
getModel().read(req.params.book_id, (err, entity) => {
if (err) {
console.log('Request Detail JSON unable to return data results. Error message: ', err);
return;
} else {
res.json(entity);
}
});
};
/*ANGULAR WITH HARD-CODED BOOK ID*/
//QUESTION: HOW TO PASS THE BOOK ID IN DYNAMICALLY?
function DetailPageController($http) {
var vm = this;
$http({
url: '/detail/json/5761233819297931', //HARD-CODED ID HOW TO PASS IN DYNAMICALLY?
method: 'GET'
}).then(function (response){
vm.book = response.data;
console.log('API worked', response);
},function (error){
console.log('API error: ', error);
});
}
UPDATE:
"This probably depends on how your application is used. For example, the app might display a list of Books fetched from Express, and the user clicks one to see the detail page. In that case, the frontend fetches the complete list of Book ID's from Express. Can you please outline the behavior of your application?"
Use Case 1:
After the user submits a the New Book form, the Node app will redirect to the URL that renders the detail page. '/detail/:book_id'. I want to use Angular to build a datatable to display the details of the book that was created.
Use Case 2:
Another use case in the future will be to display all books that were created by the logged-in user. In this case, I want to use Angular to display all the books in a datatable. The route will be something like '/mybooks/:username'. Also, the user should also be able to click on a link that brings them to the details page (use case 1) for single book.
UPDATE 2:
I tried using routeParams to extract the ID out of the URL. It appears to be exactly what I need however it isn't working. Note that the routes were created on the server side with Express, not Angular.
$routeParams //Object
$routeParams.book_id //undefined
https://docs.angularjs.org/api/ngRoute/service/$routeParams
UPDATE 3:
I was able to solve this with a bit of a hacky workaround. I'm not super satisfied with this solution since it is quite hacky but at least it works for the time being.
I used this code in the Angular controller to extract the ID from the URL.
var relpath = $location.path().split('/');
var book_id = relpath[3];
UPDATE 4:
So it looks like I am back to square one. This solution broke the express routing. I am now having the same issue as described in this thread because locationProvider HTML mode is enabled to get this solution to work. Pages aren't loading when clicking on menu links, they are only loading when typed in directly.
Angular routing doesn't work when URL is directly visited in browser but works when clicked to?
You can use template literals: in your url string.
function DetailPageController($http, id = 5761233819297931) {
var vm = this;
$http({
url: `/detail/json/${id}`, //HARD-CODED ID HOW TO PASS IN DYNAMICALLY?
method: 'GET'
}).then(function (response){
vm.book = response.data;
console.log('API worked', response);
},function (error){
console.log('API error: ', error);
});
}

error when reading json file using angular resource

I'm trying to use angular ngResource module to fetch data from json file but I get an error 404 on the console - the URL is being concatenated with code following the call to get function.
Here is the error:
localhost prefix/test_data/data.json/function%20(data)%20%7B%20%20%20%20%20%20%20%20%20%20%20%20console.log(data);%20%20%20%20%20%20%20%20%7D
here is the code I'm using:
the json service -
angular.module('jsonServices',['ngResource']).factory('JsonService',
function ($resource) {
return $resource('/test_data/data.json');
});
the controller using the service:
angular.module('myApp.controllers')
.controller('mainController', function ($scope, JsonService) {
JsonService.get(function (data) {
console.log(data);
});
});
the app js that starts it all:
angular.module('myApp',['myApp.controllers','jsonServices','ui.router'])
.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('home',{
url:'/home',
template:'some template path goes here',
controller:'mainController'
};
});
As you can see the "function(data)" is being added to the url as a string. one more thing is when I try to access the json file browsing to its location I can see the content of the json file OK.
Does anyone got this problem before and find a way to solve it? Is there something I'm doing wrong or missing here?
Thanks,
Eran
Found the problem, it seems that I used a bower package call ng-resource instead of angular-resource.

Angulars $http.jsonp() is returning 404 [duplicate]

I am trying to obtain a .json file from remote firebase server.
function fetchData(remoteJsonId){
var url = "https://myAppName.firebaseapp.com/topics/"+remoteJsonID;
console.log(url); //This variable expands to the full domain name which is valid and returns success both on wget and the browser
$http.jsonp(url).then(
function(resp){
},
function(err){
console.log(err.status) // This posts "404" on console.
}
);
}
But If I open url in the browser the json file loads. Even if I wget url the json file loads. But through angular it returns a 404 not found.
Now the .json remote file has this structure:
[
{
"hello":"Europe"
},
{
"hello":"USA"
}
]
The above file can be fetched using $http.get() but not with $http.jsonp(). JSONP cant parse .json file with the above structure. How can I work around this?
You need to specify a ?callback=JSON_CALLBACK in the URL that you pass to $http.jsonp.
From Angular's $http.jsonp documentation:
jsonp(url, [config]);
Shortcut method to perform JSONP request.
Parameters
Param Type Details
url string
Relative or absolute URL specifying the destination of the request.
The name of the callback should be the string JSON_CALLBACK.
That last line is what you're missing.
A simple example (using a Firebase database, not Firebase hosting):
var app = angular.module('myapp', []);
app.controller('mycontroller', function($scope, $http) {
var url = 'https://yourfirebase.firebaseio.com/25564200.json';
$http.jsonp(url+'?callback=JSON_CALLBACK').then(
function(resp){
console.log(resp.data); // your object is in resp.data
},
function(err){
console.error(err.status)
}
);
});
In case you want to see it working: http://jsbin.com/robono/1/watch?js,console

Getting Data from Node.js file and displaying it in HTML/JS page

I am new to Node.js and this is my first project with it.
I have made a node.js file named test.js. It has an array say a.
Now I want to make a HTML file that calls this test.js on button click event. Then get the data from that file and publish it on a table in the HTML file.
I have already written the node.js file and I can see the results on console.log(a). But I cant understand how to send this array to HTML when it will ask for it.
Meanwhile, I googled and made up some code. The request reaches the server but I always get error response from server. Why so?
Client Side -
function fetch() {
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8888",
data: 'China',
datatype: 'json',
success: function (data) {
alert("hi");
var ret = jQuery.parseJSON(data);
$('#q').html(ret.msg);
},
error: function (xhr, status, error) {
alert("hii");
}
});
Server side :
http.createServer(function(request, response) {
console.log("Request received");
response.writeHeader(200, {"Content-Type": "application/json"});
request.on('data', function (chunk) {
console.log(chunk.toString('utf8'));
consol.log(result);
response.write(JSON.stringify({data : result}));
});
response.end();
}).listen(8888);
I can see China on the console.But I dont get back the result array back to the client. Here result is an array and I get its value on the console. Just that I dont get it back to the client. Any help ?
You should start by setting up a server to serve requests. I use expressjs for this - http://expressjs.com/
This will allow you to run nodejs as a web application.
Setup a route in express JS to serve your data - http://expressjs.com/api.html#express
var express = require('express');
var app = express();
app.get('/data', function(req, res){
res.send('hello world'); //replace with your data here
});
app.listen(3000);
Open up a browser, and type in http://MY_SERVER_ADDR:3000/data and you should see your output there.
Next, you'll need to attach an event handler to your HTML file that will trigger a $.get() request when it is triggered. Add the previous url to your data in your $.get call and do something with it.
$('.my_selector').click(function(){
$.get('http://MY_SERVER_ADDR:3000/data', {}, function(data){
console.log(data)
});
});
That should get you going.
After wrestling with the same question, i found that this is exactly where a template engine comes into the node-picture.
EJS solved it for me, but there are many more available.
This article compares 10 template engines.

Categories