I want to pass Array object in $http.get(). Previously all information is stored in data.json file, But I don't want to use file. Want to define the Array of object as $scope.data in controller.
Please find DEMO
http://plnkr.co/edit/X5ZC3UGey4Zjos7W01U1?p=preview
Working DEMO http://plnkr.co/edit/o6EeKnC8oFEq3GCRsQgp?p=preview
here we are using data.json. I want to define data inside data.json in Controller, Plz tell me how to dd
.controller('QuestionCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.questions = [];
$scope.data = {
"questions": [
{
"question": "Qw1",
"answers": [
{
"answers": "An1",
"value": 25
},
{
"answers": "An2",
"value": 50
},
{
"answers": "An3",
"value": 75
},
{
"answers": "An4",
"value": 100
}
]
},
{
"question": "Qw2",
"answers": [
{
"answers": "An1",
"value": 25
},
{
"answers": "An2",
"value": 50
},
{
"answers": "An3",
"value": 75
},
{
"answers": "An4",
"value": 100
}
]
}
]
}
$http
.get(JSON.stringify($scope.data))
.then(function(response){
$scope.questions = response.data.questions;
});
}])
I'm using this, and it works great for me
$http.get('url', {params: yourArray}).then(function (result) {
//do sth with data
});
HTTP GET request can't contain data to be sent to the server. You can add a query string to the request. $http option for it is params.
$http({
url: 'example.com',
method: "GET",
params: {...}
});
You dont need to use $http.get() if the data is directly available in controller.
You can use $scope.data instead of $scope.questions. ie in your html file use
{{data.questions[0].question}}
<h2>answer 1</h2>
<p>{{data.questions[0].answers[0].value}}</p>
<p>{{data.questions[0].answers[0].answers}}</p>
I have tried this way and it is working fine:
For example in your controller you have any array like arr variable
var data = Array;
data['Id'] = "1";
data['Name'] ="Test User";
data['UserName'] = "test_user";
data['Email'] = "test#gmail.com";
data['Address'] = "Test Address";
data['Action'] = 'Create';
To pass this array you can use like this
$scope.users = data;
The controller send an array in view page as the variable users
and you can use something like this
ng-repeat="user in users"
Note: this will work for two dimensional array and one dimensional array.
AngularJS has $http service, to get data asynchronously. So it can return any type of data(variable, array, string).
It is better to store data in some common place. Let me show factory pattern which is used for sharing data between controllers.
At first, you should create yourFactory.js file and write the following code:
(function () {
var yourFactory = function () {
var persons = [
{
id: 1,
name: 'Jon',
},
{
id: 2,
name: 'Ben',
},
{
id: 3,
name: 'Joseph',
},
{
id: 4,
name: 'Adam',
}
];
var factory = {};
factory.getPersons = function () {
return persons;
};
return factory;
};
angular.module('personsApp').factory('personsFactory', yourFactory);
}());
and some your controller can use data(just create new .js file for the following controller):
(function()
{
debugger;
var yourController=function($scope, yourFactory) {
/*alert('a1');*/
debugger;
function init() {
debugger;
$scope.yourData=yourFactory.getPersons();
}
init();
};
yourController.$inject=['$scope', 'yourFactory'];
angular.module('yourAppl').controller('yourController', yourController);
}());
Related
I am using mongoose in nodejs(express) in backend. My array structure has THREE levels. At third level, some files are present. But I need to add entries at any level as per user demand.
[
{
"name": "A folder at",
"route": "level1_a"
},
{
"name":"Another folder at Level1",
"route": "level1_b",
"children":
[
{
"name": "A folder at Level2",
"route": "level1_b/level2_a",
"children":
[
{
"name": "A folder at Level3",
"route": "level1_b/level2_a/level3_a",
"children":
[
{
"name": "A file at last level",
"route": "level1_b/level2_a/level3_a/file1"
},
{
"name": "Add a new File",
"route":"level1_b/level2_a/level3_a/new_file"
}
]
},
{
"name": "Add Folder at Level3",
"route":"level1_b/level2_a/new_folder"
}
]
},
{
"name": "Add Folder at level2",
"route":"level1_b/new_folder"
}
]
},
{
"name": "Add Folder at Level1",
"route":"new_folder"
}
]
Now I have to add an entry at a specified position. Suppose at level2, I need to add a folder. For adding, two parameters are sent from angular to the backend. These will be 'name' and a 'route'. So my entry would be having {name: 'Products', route: 'level1_a/products'} and similarily should be placed at correct position i.e. inside the children of level1_a.
My backend has a schema which would be like:
const navSchema = mongoose.Schema({
name:{type:String,required:true},
route:{type:String},
children:{
type: {
name:{type:String,required:true},
route:{type:String},
}}
});
module.exports = mongoose.model('NatItems',navSchema);
And the API would be like:
router.post('/navlist',(req,res,next)=>{
const name= req.body.folder;
const route= req.body.url;
console.log(folder,url);//it will be required parameters like name: 'Products', route:'level1_a/products'
//let pathArray = route.split('/'); //if you want you can split the urls in the array
//Help me write the code here
res.status(201).json({
message:"Post added successfully!"
})
})
Please help me in adding entries in db. I know navlist.save() adds an entry directly but I am not able to add entries in a nested manner.
PS: I can't change the array structure because this array is easily read by angular and a complete navigation menu is made!! I am working for first time in nodejs and mongoose, so I am having difficulty in writing code with mongoose function.
For the scenario you've provided ({name: 'Products', route: 'level1_a/products'}) the update statement is pretty straightforward and looks like this:
Model.update(
{ route: "level1_a" },
{ $push: { children: {name: 'Products', route: 'level1_a/products'} } })
Things are getting a little bit more complicated when there are more than two segments in the incoming route, e.g.
{ "name": "Add a new File", "route":"level1_b/level2_a/level3_a/new_file2" };
In such case you need to take advantage of the positional filtered operator and build arrayFilters and your query becomes this:
Model.update(
{ "route": "level1_b"},
{
"$push": {
"children.$[child0].children.$[child1].children": {
"name": "Add a new File",
"route": "level1_b/level2_a/level3_a/new_file2"
}
}
},
{
"arrayFilters": [
{
"child0.route": "level1_b/level2_a"
},
{
"child1.route": "level1_b/level2_a/level3_a"
}
]
})
So you need a function which loops through the route and builds corresponding update statement along with options:
let obj = { "name": "Add a new File", "route":"level1_b/level2_a/level3_a/new_file2" };
let segments = obj.route.split('/');;
let query = { route: segments[0] };
let update, options = {};
if(segments.length === 2){
update = { $push: { children: obj } }
} else {
let updatePath = "children";
options.arrayFilters = [];
for(let i = 0; i < segments.length -2; i++){
updatePath += `.$[child${i}].children`;
options.arrayFilters.push({ [`child${i}.route`]: segments.slice(0, i + 2).join('/') });
}
update = { $push: { [updatePath]: obj } };
}
console.log('query', query);
console.log('update', update);
console.log('options', options);
So you can run:
Model.update(query, update, options);
I want to fetch all the names and label from JSON without loop. Is there a way to fetch with any filter method?
"sections": [
{
"id": "62ee1779",
"name": "Drinks",
"items": [
{
"id": "1902b625",
"name": "Cold Brew",
"optionSets": [
{
"id": "45f2a845-c83b-49c2-90ae-a227dfb7c513",
"label": "Choose a size",
},
{
"id": "af171c34-4ca8-4374-82bf-a418396e375c",
"label": "Additional Toppings",
},
],
},
]
}
When you say "without loops" I take it as without For Loops. because any kind of traversal of arrays, let alone nested traversal, involve iterating.
You can use the reduce method to have it done for you internally and give you the format you need.
Try this :
const data = {
sections: [
{
id: "62ee1779",
name: "Drinks",
items: [
{
id: "1902b625",
name: "Cold Brew",
optionSets: [
{
id: "45f2a845-c83b-49c2-90ae-a227dfb7c513",
label: "Choose a size"
},
{
id: "af171c34-4ca8-4374-82bf-a418396e375c",
label: "Additional Toppings"
}
]
}
]
}
]
};
x = data.sections.reduce((acc, ele) => {
acc.push(ele.name);
otherName = ele.items.reduce((acc2, elem2) => {
acc2.push(elem2.name);
label = elem2.optionSets.reduce((acc3, elem3) => {
acc3.push(elem3.label);
return acc3;
}, []);
return acc2.concat(label);
}, []);
return acc.concat(otherName);
}, []);
console.log(x);
Go ahead and press run snippet to see if this matches your desired output.
For More on info reduce method
In the context of cJSON
yes, we can fetch the key value for any of the object.
1 - each key value is pointed by one of the objects. will simply fetch that object and from there will get the key value.
In the above case for
pre-requisition: root must contain the json format and root must be the cJSON pointer. if not we can define it and use cJSON_Parse() to parse the json.
1st name object is "sections" will use
cJSON *test = cJSON_GetObjectItem(root, "sections");
char *name1 = cJSON_GetObjectItem(test, "name" )->valuestring;
2nd name key value
cJSON *test2 = cJSON_GetObjectItem(test, "items");
char *name2 = cJSON_GetObjectItem(tes2, "name")->valuestring;
likewise, we can do for others as well to fetch the key value.
I've got 2 data sets
posts
[
{
"postId": 1,
"postContent": "Lorem Ipsum",
"user": 1
},
{
"postId": 2,
"postContent": "Lorem Ipsum",
"user": 2
},
]
and users
[
{
"user": 1,
"firstName": "John",
"lastName": "Doe"
},
{
"user": 2,
"firstName": "Johny",
"lastName": "Doey"
}
]
I am repeating all the posts and i would like to access a user data throught the $scope.post.user.firstName etc.
how should i aproach it?
You can implement a method like getUserById() with the use of Array.prototype.find() to use it when iterating over your posts.
Code in AngularJS:
angular
.module('App', [])
.controller('AppController', ['$scope', function ($scope) {
$scope.posts = [{"postId": 1,"postContent": "Lorem Ipsum","user": 1},{"postId": 2,"postContent": "Lorem Ipsum","user": 2}];
$scope.users = [{"user": 1, "firstName": "John", "lastName": "Doe"},{ "user": 2, "firstName": "Johny", "lastName": "Doey"}];
$scope.getUserById = function (id) {
return $scope.users.find(function (user) {
return id === user.user;
});
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<div ng-app="App" ng-controller="AppController" class="row">
<div ng-repeat="p in posts">
<p>{{p.postContent}} <i>by {{getUserById(p.user).firstName}}</i></p>
</div>
</div>
find() the matching user for each post.
Note that if you are not using ES6 features, you will need a polyfill for Object.assign() and should use regular function() {}s instead array functions.
var posts = [{"postId":1,"postContent":"LoremIpsum","user":1},{"postId":2,"postContent":"LoremIpsum","user":2}];
var users = [{"user":1,"firstName":"John","lastName":"Doe"},{"user":2,"firstName":"Johny","lastName":"Doey"}];
var out = posts.map(post => Object.assign({}, post, {
user: users.find(user => user.user === post.user)
}));
console.log(out);
You can create a function that maps each user object to your post object. Then you can access user details as $scope.post.user.first_name; Here is simple code that will make you an new object with users.
var new_object = [];
function mapUsersToPosts(users, posts){
angular.forEach(posts, function(post){
angular.forEach(users, function(user){
if(post.user_id == user.user_id){
new_object.push({
'post' : post,
'user' : user
});
}
});
});
}
Now you can loop new_object and use user data and post data in same object.
I am working on an product reviewing app based on ionic framework.
The app will consume REST service in JSON format.
Because Im not able to retireve data directly from the locally deployed website, i created a json demo file:
[{
"index": 0,
"marque": "labore",
"estAutorise": 0,
"name": "Jennifer Simmons"
},
{
"index": 1,
"marque": "duis",
"estAutorise": 0,
"name": "Beatriz Hale"
},
{
"index": 2,
"marque": "pariatur",
"estAutorise": 1,
"name": "Richmond Garner"
}
]
here is my services.js:
angular.module('starter.services', [])
.factory('Recettes', function($http) {
var recettes = [];
var produits = [];
$http.get('test.json').success(function(data) {
alert("success"); //to check the seccess responce
produits= data;
});
return {
...
produits: function() {
return produits;
},
....
Before this, I implemented products and recettes directly and it works just fine. And now, I recieve the success alert but the data seems to be invalid.
My controller:
angular.module('starter.controllers', [])
.controller('DashCtrl', function($scope, Recettes) {
$scope.produits = Recettes.produits();
})
...
So my question is how can i fix the data binding problem ?
And If it works with .json file should it work for rest services as well (Content-Type: application/json )?
Thank you.
I'm trying to build a nested array in jQuery based on a user's selection from a drop down menu. This will be used in a JSON request at a later date.
So far my code does produce (almost) the required result, however no matter order i select the options from my drop down menu, the output (which i log in the console at the end) is always the same.
$('#comboGenre').change(function () {
var values = $('#comboGenre').val();
var parsedJSON = JSON.parse($data); //Data returned from ajax request
for (var i = 0; i < values.length; i += 1) {
$genreList = parsedJSON.genre[i];
console.log($genreList);
}
});
So if i select RPG and Action from my drop down, the output gives me RPG and Driving. If i selected RPG, Driving and Action (in that order), i get what i would expect RPG, Driving and Action.
So it's just iterating through my JSON, when really it should be returning the 'selected' option.
How can i achieve this?
My JSON looks like this if it's useful:
{"genres": [{
"genre": "RPG",
"publishers": [{
"publisher": "Square",
"games": [{
"game": "FFX",
"rating": [
12, 15
]
}]
}]
},
{
"genre": "Driving",
"publishers": [{
"publisher": "Turn10",
"games": [{
"game": "Forza",
"rating": [
5
]
}]
}]
},
{
"genre": "Action",
"publishers": [{
"publisher": "EA",
"games": [{
"game": "COD",
"rating": [
18, 20
]
}]
}]
}
]}
EDIT:
I've also tried this:
$('#comboGenre').change(function () {
var parsedJSON = JSON.parse($data);
$genreList = "";
$.each(parsedJSON.genres, function(index, value){
$genreList = parsedJSON.genres[index];
console.log($genreList);
});
});
And i end up getting ALL the objects in my JSON, so from here, i'm only wanting to add the selected object to the $genreList variable.
If you broke out some of the logic and created a genre finding function and used the selected string to find the proper object you could then put the object into the variable you will use later. I do some checking to ensure that the genre that has been selected isn't already in my array which is because I am using the multiple select
JSFiddle: http://jsfiddle.net/vkTFq/
Code:
$(function(){
var selectedGenres = [];
var genres =[{"genre":"RPG","publishers":[{"publisher":"Square","games":[{"game":"FFX","rating":[12,15]}]}]},{"genre":"Driving","publishers":[{"publisher":"Turn10","games":[{"game":"Forza","rating":[5]}]}]},{"genre":"Action","publishers":[{"publisher":"EA","games":[{"game":"COD","rating":[18,20]}]}]}]
$('#comboGenre').change(function() {
$(this).find(":selected").each(function() {
var selectedGenre = findGenre($(this).val())
if (!genreAlreadySelected(selectedGenre.genre)) {
selectedGenres.push(selectedGenre);
};
});
console.log (JSON.stringify(selectedGenres));
});
function genreAlreadySelected(genre){
for(var i = 0; i < selectedGenres.length; i++){
if (genre == selectedGenres[i].genre) {
return true;
};
return false;
}
}
function findGenre(genre){
for(var i = 0; i < genres.length; i ++){
console.log(genre)
if(genre == genres[i].genre){
return genres[i];
}
}
};
});