Make AngularJS service call async - json

I have read about "promise" object and all the ways to get some sort of async call or wait until a http call is done, but I haven't been able to success. This is what I got and what I'm trying to do:
I need to get some json file from my server and use the data from that json in my code (js file) and not only as data for my HTML template.
I have a service that does the call to the json file:
mobilityApp.service('serveiWebservices', function($resource) {
return {
getWS: function($scope) {
var path = 'jsonWS/context.json';
$resource(path).get(function (data) {
console.log(data); //data is printed fine
$scope.returnData = data; //just to test, it doesn't work neither
return data;
});
}
};
});
And from my controler I call it like this:
var data = serveiWebservices.getWS($scope);
console.log(data); //undefined
any idea on how to work with the promise object that the funcion returns and perform actions as soon as it gets the requested data ? i Know that I could set a "success" function but I would like not to use callbacks.
Tnanks in advance !

This should work -
Service:
mobilityApp.service('serveiWebservices', function($http) {
return {
getWS: function() {
var path = 'jsonWS/context.json';
return $http.get(path, function (response) {
console.log(JSON.stringify(response, null, 4));
return response.data;
});
}
};
});
Controller:
serveiWebservices.getWS().then(function(data) {
console.log(JSON.stringify(data, null, 4));
});
If you want to use $resource this should work too -
mobilityApp.service('serveiWebservices', function($resource) {
return {
getWS: function() {
var path = 'jsonWS/context.json';
return $resource(path).get(function (response) {
console.log(JSON.stringify(response, null, 4));
return response; // might just be response, no response.data
});
}
};
});

I was searching for a working solution from hours. thanks #Ross.
This also work , i modified the Ross example , and removed the first return :
mobilityApp.service('serveiWebservices', function($http) {
this.getWS = function() {
var path = 'jsonWS/context.json';
return $http.get(path, function (response) {
console.log(JSON.stringify(response, null, 4));
return response.data;
});
}
this.getWS2 = function() {
var path = 'jsonWS2/context.json';
return $http.get(path, function (response) {
console.log(JSON.stringify(response, null, 4));
return response.data;
});
}
});
If i get a lot of function in this service should i use the Ross example with all the function in the return or this one ? thanks

Related

Laravel Return Value from Controller via JS Get Method

I am trying to create a Request via Axios JS to the API Route and trying to send the data from the database over the controller back to the view of the page. When I am just put an string as return value it is working.
I am always getting following a 500 Error.
JS File
function getSelectedItem() {
var e = document.getElementById("Objekt");
if (e.value > 0) {
axios({
method: 'get',
url: '/api/zimmer/' + e.value,
responseType: 'stream'
})
.then(function(response) {
zimmer_select.disabled = false;
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
} else {
zimmer_select.disabled = true;
}
console.log(e.value);
}
API Route:
Route::controller(MieterController::class)->group(function () {
Route::get('/zimmer/{id}', 'relocate_update')->name('api.get.zimmer');
});
Controller:
public function relocate_update($id) {
$zimmer_zu_objekt = Zimmer::findOrFail()->where('objekt_id', $id);
return response()->json(['alle_zimmer' => $zimmer_zu_objekt], 200);
}
I got it.
I changed it to VanillaJS and the main problem was my Eloquent Query in the Controller. Corret is
return Zimmer::where('objekt_id','=', $id)->get();
and used the fetch-method is JS:
fetch('/api/zimmer/' + e.value)
.then(function(response) {
zimmer_select.disabled = false;
console.log(response.json());
})
.catch(function(error) {
console.log(error);
});

d3 - Can't return data from json request?

I'm trying to use d3.json() inside of a function to return data Spotify's API given an artist ID (such as 5K4W6rqBFWDnAN6FQUkS6x), but I can't figure out how to effectively return the data. The function looks like
// Get artist's related artist's information
function relatedArtists(id){
var jsonPromise = new Promise(function(resolve, reject) {
// Async JSON request
d3.json('https://api.spotify.com/v1/artists/' + id + '/related-artists', function(error, data){
if(error) reject(error);
resolve(data.artists);
});
});
jsonPromise.then(function(success) {
console.log(success);
//return(success) //doesn't work
});
jsonPromise.catch(function(error){
console.error(error);
});
}
I've tried creating a variable within the function and then modifying it
function relatedArtists(id){
var testVar = 'hello';
var jsonPromise = new Promise(...{
// Async JSON request
d3.json(...)
});
jsonPromise.then(function(success) {
testVar = success;
});
return(testVar);
}
But testVar remains 'hello', despite my best efforts. I've done some reading about scope and promises, but am happy to do more if there's some core mechanic of either that I'm not understanding. Thanks for reading!
The response will never be available in your calling code due to asynchronous nature of requests. You can use Promises (as supposed by Alexander T. and you, good choice in many cases!) but d3.queue does a good job, too. In my snippet you can see how to run code with the results of multiple requests.
function buildRelatedArtistUri(id) {
return 'https://api.spotify.com/v1/artists/' + id + '/related-artists';
}
d3.queue()
.defer(d3.json, buildRelatedArtistUri('5K4W6rqBFWDnAN6FQUkS6x'))
.await(function(error, data) {
// data and data.artists are available in this function‘s scope only
console.log(data.artists);
});
d3.queue()
.defer(d3.json, buildRelatedArtistUri('5K4W6rqBFWDnAN6FQUkS6x'))
.defer(d3.json, buildRelatedArtistUri('3nFkdlSjzX9mRTtwJOzDYB'))
.await(function(error, data1, data2) {
// this function will be called once both functions have finished
console.log(data1.artists, data2.artists);
});
<script src="https://d3js.org/d3.v4.min.js"></script>
You can return Promise and use relatedArtists function like so
function relatedArtists(id) {
return new Promise(function(resolve, reject) {
d3.json('https://api.spotify.com/v1/artists/' + id + '/related-artists', function(error, data) {
if (error) {
reject(error);
} else {
resolve(data.artists);
}
});
});
}
relatedArtists('5K4W6rqBFWDnAN6FQUkS6x')
.then(function (data) {
console.log(data);
})
.catch(function (error) {
console.log(error);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
In this case, you can not assign the value to testVar, because d3.json is the asynchronous method and that means that d3.json can be done after code execution.

how to update a variable in es6 inside a fetch function?

I have this code below:
let courses = '';
fetch(link)
.then(function(response) {
return response.json();
}).then(function(json) {
courses = json;
}).catch(function(ex) {
console.log('parsing failed', ex);
});
Using console.log(courses) prints out ''.
How do I set it to the retrieved json?
The fetch method is asynchronous, essentially, you will only have access to the json content in the courses variable after the fetch promise resolves. Try doing the following:
function synchronousCode(courses) {
console.log('courses', courses); // output json courses
}
fetch(link)
.then(function(response) {
return response.json();
})
.then(synchronousCode)
.catch(function(ex) {
console.log('parsing failed', ex);
});
One of the benefits of using the Fetch API is that you can neatly chain your methods instead of just having one "synchronousCode" function. Here's an example:
function asynchronouslyAnalyze(courses) {
return new Promise(function(resolve, reject) {
setTimeout(function () { resolve(courses) }, 1000);
});
}
function parse(courses) {
// do something with courses
return courses;
}
function print(courses) {
console.log('courses', courses); // output courses json
}
function toJSON(response) {
return response.json();
}
fetch(link)
.then(toJSON)
.then(asynchronouslyAnalyze)
.then(parse)
.then(print)
.catch(function(ex) {
console.log('parsing failed', ex);
});
I hope that helps!

Fetching data from local JSON File in angularjs

I want to fetch data from JSON file which is on my local machine. But I am not able to get the data. It is showing some cross domain error for $http.
Here is my code.
angular.module('myApp',[])
.controller('myCtrl', function ($scope, webtest) {
webtest.fetch().then(function (data) {
$scope.accounttype = data;
})
});
.factory('webtest', function($q, $timeout, $http) {
var Webtest = {
fetch: function(callback) {
return $timeout(function() {
return $http.get('webtest.json')
.then(function(response) {
return response.data;
});
}, 30);
}
};
return Webtest;
});
Anyone please help me how to display data from local JSON file?
Thanks in Advance.
It's very simple like
$http.get('phones/phones.json').then(function(response) {
$scope.phones = response.data;
});
Refer:http://stackoverflow.com/questions/21589340/read-local-file-in-angularjs
Don't you have an error message like "$http: is not defined" ?
I tried with a controller, this is working :
var ngApp = angular.module("ngApp", []);
ngApp.controller('myController', ['$http', function($http){
var thisCtrl = this;
this.getData = function () {
this.route = 'webtest.json';
$http.get(thisCtrl.route)
.success(function(data){
console.log(data);
})
.error(function(data){
console.log("Error getting data from " + thisCtrl.route);
});
}
}]);
If you haven't, use web developer tools (Ctrl+Shift+I in firefox).
If you haven't already done so. Try setting up a crossdomain policy for your application.

AngularJS : Factory JSON Array with HTTP GET

I'm developing my first AngularJS app using the Google Docs API to pass it JSON data.
This is an example of the factory I'm using:
app.factory('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
return {
news:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/1/public/values?alt=json', {cache: true});
},
updates:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/2/public/values?alt=json', {cache: true});
},
docs:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/3/public/values?alt=json', {cache: true});
}
}]);
I wanted to clean up a bit the code and decided to use services instead of making the calls in the controller itself. It works normally, but it's a pain in the ass the fact that I still need to write long $scopes because of the structure of the Google API. This is how I get the values in the controller:
app.controller('homeCt', ['$scope', 'Data', function ($scope, Data){
Data.news().success(function (data) {
$scope.totalNews = data.feed.entry.length;
});
}]);
Is there a way that I can set the factory service to pass me the data just using:
$scope.totalNews = Data.news()
Or at least removing the 'feed.entry'?
Data.news().success(function (data) {
$scope.totalNews = data.length;
});
Thank you very much!
example of service - resolve the success with the data you want
app.service('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
this.news =function(){
return $http.get(googleDocs + apiKeys.googleDoc +'/1/public/values? alt=json', {cache: true})
.then(function(data){
return data.feed.entry.length;
});
}
}]);
the controller - since you already resolved the data in service hence..
app.controller('homeCt', ['$scope', 'Data', function ($scope, Data){
Data.news().then(function (data) {
$scope.totalNews = data;
});
}]);
working example
var app = angular.module('app', ['ionic'])
.service('Data', ['$http',
function($http) {
var googleDocs = 'https://spreadsheets.google.com/feeds/list/1aC1lUSxKatfxMKEy1erKDSAKgijSWOh77FDvKWhpwfg/1/public/values?alt=json';
this.news = function() {
return $http.get(googleDocs, {
cache: true
}).then(function(res) {
return res.data.feed.entry;
});
}
}
])
.controller('homeCt', ['$scope', 'Data',
function($scope, Data) {
Data.news().then(function(data) {
console.log(data);
})
}
]);
I'll give you a way of doing it, a way that I don't recommend at all (a service should not handle the scope), but for me it is the only way you have if you don't want to destroy the "async" of your ajax call :
app.factory('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
return {
news:news,
updates: updates,
[...]
}
function news(scopeValue) {
$http.get(googleDocs + apiKeys.googleDoc +'/1/public/values?alt=json', {cache: true}).success(function(data){
scopeValue = data;
});
}]);
and then, call it that way in your controller :
Data.news($scope.totalNews);