I'm having some problems on making a request from angular to my Java backend.
My current code is this:
$scope.listdevices=function(){
var devices = $resource('http://localhost:8080/userapi/devices/:userId',{userId:'#userId'});
var list=devices.query({userId:$scope.userId});
console.log(JSON.stringify(list));
console.log(list);
console.log(list.length+"TAMANHO")
};
The data is being being fetched and it looks like this:
But the objects are not being saved in my list when I call listdevices to return a list of objects to iterate.
Thanks a lot
.query will be async, so you need a callback or a promise. Anyway, if you are trying to get a single record, you use "get". Here you have an example:
myApp.factory('Device', function($resource) {
return $resource('http://localhost:8080/userapi/devices/:userId', {
userId: '#userId'
});
});
myApp.controller('YourCtrl', function(Device) {
Device.get({
userId: 1
}).$promise.then(function(res){
console.log(res)
})
})
.query is for query your endpoint, for example if you wanted to search devices with conditions. Resource assumes that 'http://localhost:8080/userapi/devices' will return an array, while /:userId will return an object.
Extending the answer as per your comment, if you wanted to query a list of devices of a certain users (which returns an array), you would indeed use .query
Device.query({
userId: 1
}).$promise.then(function(results) {
console.log(results)
})
Alternatively, if you use a callback you have access to the headers.
Device.query({
userId: 1
}, function(results, headers) {
})
Related
I am trying to create a API using nodejs and access it using GET method by sending parameters using Angular 5 GET method. When I am testing my API using Postman, it works fine, but sending the GET request from Angular is not giving me the result. My node js router for receiving multiple parameters code is as follow:
router.get('/:min&:max',(req,res,next)=> {
Image.find({hue: {$gt:req.params.min,$lt:req.params.max}})
.select('name url hue')
.exec()
.then(docs => {
const response={
images: docs.map(doc=> {
return {
name: doc.name,
url: doc.url,
hue: doc.hue,
_id: doc._id,
}
})
}
res.status(200).json(docs);
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
})
My angular GET method goes like this :
getSearchedImages(min, max) {
let params = {
'min': String(min),
'max': String(max)
}
this.http.get('http://localhost:3000/', { params: params})
.subscribe(val=> console.log(val))
}
Is there any problem in Angular part or is my code in Node is to be adjusted
Use POST if you want to pass parameters in request body. Otherwise, if you like GET, pass parameters in URL.
HTTP itself doesnt restrict this, but some front-end implementations do
What is the 'meteor'-way to get a document title by a given ID?
Collection (Articles)
{
'_id' : 'Dn59y87PGhkJXpaiZ',
'title' : 'Sample Article',
'slug' : 'sample-article'
}
client
render() {
const data = [
{ _id: 'Dn59y87PGhkJXpaiZ' },
{ _id: 'kJXpaiZDn59y87PGh' }
{ _id: 'y87PGhkJXpaiZDn59' }
]
return (
<List>
{
data.map(r => {
return <List.Item>r._id</List.Item>
})
}
)
}
With this I will get this output:
<List>
<List.Item>Dn59y87PGhkJXpaiZ</List.Item>
<List.Item>kJXpaiZDn59y87PGh</List.Item>
<List.Item>y87PGhkJXpaiZDn59</List.Item>
</List>
Now I want to display the title instead of the id. So normally I would do
data.map(r => {
const title = Articles.findOne({ _id: r._id }).title
return <List.Item>title</List.Item>
})
But the problem is, that data is a dynamic dataset and I can't/don't want to publish the complete Articles collection. Right now there is no subscription, so I don't get any results for the title.
So I think I have to do a server side call.
Meteor.call('getTitle', r._id, function(err, res) {
console.log(res)
})
But then I'll get the result in the callback function. So how do I get these into the list? Also I want to avoid multiple method calls. I think it would be better to send data and get all titles on server side and then build the list.
If you can/want to use a non async call, don't pass a callback to the Meteor.call() method:
data.map(r => {
const title = Meteor.call('getTitle',r._id);
return <List.Item>title</List.Item>
})
As stated in the docs:
If you do not pass a callback on the server, the method invocation will block until the method is complete. It will eventually return the return value of the method, or it will throw an exception if the method threw an exception.
To fetch and render the data meteor way you have to use the package called react-meteor-data to create createContainer.
For example if you were to use it then you would be able to pass it directly to the component as props.
export default createContainer((props) => {
Meteor.subscribe('questions');
return {
questions: Questions.findOne({_id: props.match.params.id})
};
}, QuestionDo);
I am trying to implement a search function where a user can return other users by passing a username through a component. I followed the ember guides and have the following code to do so in my routes file:
import Ember from 'ember';
export default Ember.Route.extend({
flashMessages: Ember.inject.service(),
actions: {
searchAccount (params) {
// let accounts = this.get('store').peekAll('account');
// let account = accounts.filterBy('user_name', params.userName);
// console.log(account);
this.get('store').peekAll('account')
.then((accounts) => {
return accounts.filterBy('user_name', params.userName);
})
.then((account) => {
console.log(account);
this.get('flashMessages')
.success('account retrieved');
})
.catch(() => {
this.get('flashMessages')
.danger('There was a problem. Please try again.');
});
}
}
});
This code, however, throws me the following error:
"You cannot pass '[object Object]' as id to the store's find method"
I think that this implementation of the .find method is no longer valid, and I need to go about returning the object in a different manner. How would I go about doing this?
You can't do .then for filterBy.
You can't do .then for peekAll. because both will not return the Promise.
Calling asynchronous code and inside the searchAccount and returning the result doesn't make much sense here. since searchAccount will return quickly before completion of async code.
this.get('store').findAll('account',{reload:true}).then((accounts) =>{
if(accounts.findBy('user_name', params.userName)){
// show exists message
} else {
//show does not exist message
}
});
the above code will contact the server, and get all the result and then do findBy for the filtering. so filtering is done in client side. instead of this you can do query,
this.store.query('account', { filter: { user_name: params.userName } }).then(accounts =>{
//you can check with length accounts.length>0
//or you accounts.get('firstObject').get('user_name') === params.userName
//show success message appropriately.
});
DS.Store#find is not a valid method in modern versions of Ember Data. If the users are already in the store, you can peek and filter them:
this.store.peekAll('account').filterBy('user_name', params.userName);
Otherwise, you'll need to use the same approach you used in your earlier question, and query them (assuming your backend supports filtering):
this.store.query('account', { filter: { user_name: params.userName } });
I have a sample code that goes like this:
Client Helper:
getUsername: function (userId) {
Meteor.call("getUsername", userId, function (err, result) {
if(!err) {
Session.set("setUsername", result);
else {
console.log(err);
}
});
return Session.get("setUsername");
}
Server
Meteor.methods({
"getUsername": function (userId) {
var x = Meteor.users.find({_id: userId}, {fields: {username:1}}).fetch()[0];
return x.username;
}
});
The result of this code is an infinite loop of username passing to the client. Is there a way to stop the loop and pass only the data that is needed on the client? I believe the reactivity is causing the data to loop infinitely and I am not sure how to stop it. I tried using "reactive":false on my query in the server but it does not work.
If you want to access username everywhere in client templates (so thats why you put it into session), I would not set it in template helper. I would set it on startup and get username from session in template helpers (without calling server method)
If you need username just in one template, so you want to return its value from your template helper, do not put it into session, just return it in your server method callback.
Based on your sample code, I assume, you have a set of posts and you are retrieving user name based on user id for each post. Then instead of doing it this way, you should use publish composite package to publish related users as well.
Meteor.publishComposite('getPosts', function (postIds) {
return [{
find: function() {
return Posts.find({ _id: { $in: postIds }});
// you can also do -> return Posts.find();
// or -> return Posts.find({ /* or what ever your selector is to get the posts you need*/ });
},
children: [{
find: function(post) {
return Meteor.users.find({
id: post.userId //or the correct field in your post document to get user id
}, {
fields: {
"profile": 1
}
});
}
}}
}]
});
This way your publication will take care of publishing related users along with posts. You don't need to use methods and call them each time.
I'm working on a simple restaurant menu. And I need to filter list of dishes accordingly to the category in which we are now in current moment. The problem is in a strange behaviour of a this.store.filter(...) method. It doesn't return anything...
I want to use it like this:
App.DishRoute = Ember.Route.extend({
model: function (param) {
return this.store.filter('dish', function(dish) {
return dish.get('category_id') == param.category_id;
});
}
});
but for the test purpose I'm using this.store.filter('dish', function() {return true;}); in my example here http://jsbin.com/AcoHeNA/43/.
Please review the code and tell me what am I doing wrong or show me the way I should filter the data.
store.filter doesn't query the server, it just filter the already loaded data in the store. In your case because you don't load data in any moment, the filter will return a empty result. You can fix it calling this.store.find('dish'); to load data from the server, so any filter('dish', ...) will be updated.
App.DishRoute = Ember.Route.extend({
model: function (param) {
console.log(param.dish_id);
// pre load the data
this.store.find('dish');
// filter the prefetch data, when update the filter when new data are loaded
return this.store.filter('dish', function(){return true;});
}
});
This is the updated jsbin http://jsbin.com/akeJOTah/1/edit
This is an overview of the most used store methods:
store.find('dish') => send a request with /dishes
store.find('dish', 1) => send a request with /dishes/1
store.find('dish', { name: 'some' }) => send a request with /dishes?name=some
store.filter('dish', function() { ... }) => client side filtering, don't send a request, just filter the data present in the store
store.filter('dish', function() { ... }, { foo: 'bar' }) => run the find with query (item 3) and perform a client side filtering
store.all('dish') => don't send request, just get all the data loaded in the store