I feel like tons of people do this all the time, and yet I have been unsuccessful in finding similar examples.
I am getting data from the backend using angularJS ($http.post) to a controller in a javascript file, and presenting it in one html. The data is received after sending a search query from that html. Now, I want to "export" that data to another JS file and to present some of it again, in a new html. The problem is that I have access to that data only through the Search Controller during the searching session, and I probably need to store it somehow or send it to another controller/ JS file.
Unfortunately, I cannot use $cookies. Also, I am trying to avoid sending a new request through the server if I don't have to.
I have read a some about services in angular, however, I am new to angular (and UI in general), and for some reason was unable to implement this for my specific case.
Here is an example of the relevant controller, after getting a search request from the html page:
app.controller('SearchCtrl', ['$scope', '$http',
function($scope, $http) {
$scope.searchJSON = {
searchToken: [],
searchOption: []
$scope.sendSearch = function() {
//preparing JSON to send request to server
$scope.searchJSON["searchToken"] = this.search.searchToken;
$scope.searchJSON["searchOption"] = this.search.searchOption;
var json = $scope.searchJSON;
//sending and getting response (JSON object)
$http.post("http://some_host", json)
.success(function(response) {
$scope.collections = response.searchResults;
});
};
}]);
So the data I am interested in passing on to another JS file is in $scope.collections , which is a JSON file (I don't want use the same JS file for both html pages, so was hoping to call that data from a new controller in a new JS file).
Will appreciate any answers, leads, or similar examples from the web. Thank folks!
One possible way to solve this is by using sessionStorage/localStorage on $window. You can store your data there and after redirecting to another file, you can use it by invoking.
You are right to bring up services because that is how I would personally implement this. Create a service to handle the search request and also to store the result via promises:
angular.module('yourModule')
.factory('searchService', function($http, $q) {
var searchService = {
resultsPromise: null,
sendSearch: function(token, option) {
var dfd = $q.defer();
var json = {
searchToken: token,
searchOption: option
};
$http.post("http://some_host", json).then(
function(response) {
// resolve your deferred
dfd.resolve(response.data);
},
dfd.reject
);
this.resultsPromise = dfd.promise;
return dfd.promise;
}
};
return searchService;
});
Then in your current controller, just do:
app.controller('SearchCtrl', ['$scope', 'searchService',
function($scope, searchService) {
$scope.searchJSON = {
searchToken: [],
searchOption: []
$scope.sendSearch = function() {
searchService.sendSearch($scope.searchJSON.searchToken, $scope.searchJSON.searchOption);
};
Then in your other file, simply look at the currentResults of the same service:
app.controller('OtherCtrl', function($scope, searchService) {
if (searchService.resultsPromise) {
searchService.resultsPromise.then(function(results) {
$scope.results = results;
});
}
});
You can ditch the $http service and use $resource instead. From there you can use $cacheFactory as seen in this post: How to cache an http get service in angularjs
An alternative solution is http://jmdobry.github.io/angular-cache/ which works well with ngResource and can also easily be configured to sync to localStorage, so requests don't need to be re-done after page refresh.
`$resource('my/kewl/url/:key', { key: '#key' }, {
'get': { method: 'GET',
cache: $angularCacheFactory('MyKewlResourceCache', {
storageMode: 'localStorage' })
}
});`
Related
I'm using node with express and I want access object sent by server.
For example
server side:
router.get('/some_page/', (req, res) => {
res.render('some_page', {
data: {"somevar1":"somevalue", "somevar2":"somevalue2"}
});
});
client side javascript:
var objSentFromSrv = ??? // here i want this object and then perform some action on it
Is this possible/legitimate?
EDIT:
I'm using handlebars as template engine.
Figured out somehow.
function middlewareAppendingLocals(req, res, next) {
res.locals.layoutV = myValue;
next();
}
router.post('/page/', middlewareAppendingLocals, (req, res) => {
res.render('page_to_render');
});
In my case this variable is from database and I'm giving it based on id posted from antoher page. But still how can I access it from javascript, not only form .hbs layout file.
Then page_to_render have and I can you handlebars {{}} to get it.
You need to encode the object as JSON like this:
router.get('/some_page/', (req, res) => {
res.send(JSON.stringify({
data: {"somevar1":"somevalue", "somevar2":"somevalue2"}
}));
});
and then use AJAX on the front-end, using jQuery you can use
$.get('/some_page/', function(data) {
var objSentFromSrv = JSON.parse(data);
});
or shorter:
$.getJSON('/some_page/', function(data) {
var objSentFromSrv = data;
});
Yes. This is possible and legitimate. Assuming you are using EJS, add a line like this to your template:
<script>
const objSentFromSrv = <%-JSON.stringify(data)%>;
</script>
If you're using a different templating engine, you'll just need to look up the specific syntax on how to serialize objects.
AjAX is overkill for this use-case.
If you are using AngularJS as your front end service, you can create a controller and have it inject $scope and $http to get the data. For example:
var app = angular.module('myApp', []);
app.controller('mainController', ($scope, $http) => {
$scope.data= {};
$scope.getData = function() {
$http.get('/some_route/')
.success((data) => {
$scope.data = data;
console.log(data);
})
.error((error) => {
console.log(error);
});
};
});
And then in the front end, call getData().
https://docs.angularjs.org/guide/controller
Your templating engine is going to take the arguments passed to that render call and produce HTML (often) or JSON. It's not really sending objects, just text data.
If you're looking to change the state of some object that exists on the server side, you'll want to create some sort of API to do that. Send data down to the client, make changes to that data, then send it back to the server to be incorporated into the original object.
I am using Handlebar js and found to get server-side data at client side Javascript just using {{{ server-side JSON }}
`
Server-side Code send JSON adminData on the client side
return h.view('reports' ,{ adminData: request.auth.credentials});
Client side Code to get adminData inside script tag
console.log("{{{adminData}}}")
As a beginner in Spark framework and AngularJS I was trying to build a simple REST application. However I apparently can’t retrieve data from the server and display using Angular.
I started with simple task:
#Data
public class Todo {
private String title = "foo";
private String description= "bar" ;
}
In order to display the todo in the browser I send a JSON object as a response to get request.
get("/tasks", (request, response) -> {
response.type("application/json");
Todo todo = new Todo();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
String data = mapper.writeValueAsString(todo);
return data;
});
The Angular part looks as follows:
(function() {
var app = angular.module('todoapp', []);
app.controller('TaskController', ['$http', function($http) {
var store = this;
store.tasks = [];
$http.get('/tasks').success(function(data) {
store.tasks = data;
});
}]);
})();
And the index.html :
<ul ng-controller="TaskController as taskCtrl">
<li ng-repeat="task in taskCtrl.tasks">{{task.title}}, {{task.description}}</li>
</ul>
After running Spark and entering http://localhost:4567/tasks in the browser,it shows only JSON representation:
{
"title": "foo",
"description": "bar"
}
What am I doing wrong?
In your Spark code you are creating a '/tasks' endpoint, which you are attempting to hit with your angular code. When you try to run this in the browser, you are just hitting your '/tasks' api endpoint which is returning the expected response. You need to create another endpoint in Spark which will serve up the appropriate HTML and JavaScript code.
I'm not sure what version of angular you are using but in the version I use $http returns a different data structure than the one you show.
So to get the data from an $http request I would do something like,
$http({
url: '/tasks',
method: 'get'
}).then(function(result){
$scope.tasks = result.data;
});
The result.data is where the data structure on $http returns differ from what I see in your code.
Try console.log(data) to get a look at what the call is getting back.
I am newbie at Angular and I don't really know how to solve this problem. I have looked online and read the documentation, but I haven't found a proper answer. I also asked coworkers about this issue. They couldn't figure it out to assist me, so I thought it would be best to ask you guys about what the best way to solve this is.
Basically, the app is supposed to change the json data when the user clicks link in the menu. It is supposed to grab the current index and then display the corresponding data based on that index in the array. I will post the code that I have so far.
Here is a link to the code on Plunker.
app.factory('quest', ['$http', function($http) {
return $http({
method: 'GET',
url: 'data/study.json'
}).success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
In order to use HTTP requests I would suggest to use the following pattern:
app.factory('quest', function($http, $q) {
var promise;
return {
getQuests: function() {
// $http returns a promise, so we don't need to create one with $q
promise = $http.get('data/study.json')
.then(function(data) {
return data;
}, function(err) {
return $q.reject(err);
});
return promise;
}
}
});
So later you can fetch the factory in your Controller with:
quest.getQuests()
.then(function(data) {
$scope.data = data;
}, function(res) {
if(res.status === 500) {
// server error, alert user somehow
} else {
// probably deal with these errors differently
}
});
You can find the pattern here: https://stackoverflow.com/a/18383845/1918775
There is also a good example of saving data under a factory so you need only one HTTP request to get data from web-service.
Thanks everyone for your answers. I ended up figuring it out. What I did was created a function to search the array and I passed in the current term. The function returned a data associated with that item.
I created a project which contains spring rest service that provides json format and angularJS Client which consumes the service and that work perfectly. Now I create another project which contains just the client (angularjs and html views) but I don't know how to access my rest service from this project.
This is what I have done :
angular.module('workflowService', ['ngResource']).
factory('Demande', function ($resource) {
return $resource('/rest/employee/:id', {}, {
'save': {method:'PUT'}
});
});
function EmployeeListController($scope, $location, Employee) {
$scope.employees = Employee.query();
$scope.gotoEmployeeNewPage = function () {
$location.path("/employee/new");
};
$scope.deleteEmployee = function (employee) {
employee.$delete({'id':employee.idEmp}, function () {
$location.path('/');
});
};
}
Any help please ?
You probably want to consume the REST service that your Spring back-end is providing. You should use the built-in Angular $http service to make calls to your back-end.
Make sure CORS is enabled on your back-end to allow different origins to make requests.
I currently have a factory which I'm using to retrieve a config file.
m.factory('clientConfig', function($resource) {
var r;
r = $resource('assets/config.json', {}, {
query: {
method: 'GET'
},
isArray: false
});
return r.query();
});
The config file is a json file which contains the location of a nodeJS server. In my local environment, the json file is
{
"serverURL": "http://localhost\\:3000"
}
When I start my app on the front page this is fine. The front page loads the clientConfig module, and any subsequent page just uses the clientConfig module like below without any problem
m.factory('House', function($resource, clientConfig) {
return $resource(clientConfig.serverURL + '/houses/:houseId',
...
The problem I'm running into is if I enter the site on a page that immediately wants to load data from the server. In that case, because clientConfig is not populated yet and still empty and this stuffs up my $resource(clientConfig.serverURL + '/houses/:houseId' call.
My question is is it possible to load up clientConfig synchronous or at least have my app not start until after clientConfig has been populated?
You can't. Since JavaScript is (mostly) single threaded, there are very very few blocking operations. XHR is not one of those. There is no way to make it synchronous.
Depending on your angular version, you can either $then or $promise it:
clientConfig.$then(function (){ do something})
or
clientConfig.$promise.then(function () {do something else})
You can't. $resource always returns asynchronous data. If you want synchronous data then use $http instead of $resource.
Change your service like this;
m.factory('clientConfig', function($http) {
var get = function {
$http.get('assets/config.json').success(function(data)){
return data.serverURL;
});
};
});
And call the service like;
clientConfig.get();