How to select an item from json data with ngResource? - html

I'm trying to select data from my json file with
$resource request :
Im using a global variable productSelected in my controller,
but when I change it's value with ng-model , that don't do an effect on the model and the value of reference still the same!
Anyone have an idea please ?
Here is my code :
var myApp = angular.module('myApp', ['ngResource']);
myApp.factory('Produits',['$resource', function ($resource) {
return $resource('data/produits.json/:id',{id: "#id"},
{
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
}
);
}]);
myApp.controller('produitsCtrl', function($scope, $http,Produits,$log) {
$scope.productSelected=0;
Produits.query(function(data){
$scope.produits=data;
$scope.reference=$scope.produits[$scope.productSelected].reference ;
});
});
<div ng-app="myApp" >
<div ng-controller="produitsCtrl">
Product : <input type="text" ng-model="productSelected"/> {{ productSelected }} <br/>
Reference : {{reference}}
</div>
</div>
produits.json
[{
"id" : 1,
"reference": "AA"
},
{
"id" : 2,
"reference": "BB"
}]

Just have a look at this code may be helpful for you
<body ng-app="myApp" data-ng-controller="MainCtrl" id="div1">
Product : <input type="text" ng-model="productSelected" ng-change="fun(productSelected)"/> {{ productSelected }} <br/>
Reference :<p ng-model="reference"> {{reference}} </p>
<script>
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope){
$scope.productSelected=0;
$scope.produits= [{
"id" : 1,
"reference": "AA"
},
{
"id" : 2,
"reference": "BB"
}];
$scope.reference=$scope.produits[$scope.productSelected].reference;
$scope.fun=function(val){
//alert(val)
if(val!=undefined && val!=null && val!='')
$scope.reference=$scope.produits[$scope.productSelected].reference;
else
$scope.reference=$scope.produits[0].reference;
};
});
</script>
</body>

Related

Parse HTML from a nested JSON file with AngularJS

I am trying to parse nested JSON with AngularJS. There are items in it which will used throughout the page, however there are also nested news items in there. I'm not sure how to work this out.
test.json
{
"CustomerName" : "TEST",
"PaidCustomer" : true,
"LaunchEndDate" : "24-07-2021",
"LauncherTitle" : "Launcher Title",
"LauncherSlogan" : "LauncherSlogan",
"CommunityLogo" : "logo.jpg",
"news" : [
{
"Title" : "News 1",
"Description" : "Newsmessage 1",
"FeaturesImage" : "",
"Author" : "Hutserino",
"Tags" : [ "#launcher", "#HellYeah" ],
},
{
"Title" : "News 2",
"Description" : "news 2",
"FeaturesImage" : "",
"Author" : "Hutserino",
"Tags" : [ "#launcher", "#HellYeah" ]
}
]
}
I've already tried this:
Angular code
<script>
(function() {
angular.module('myApp', []);
function myController($scope, $http) {
return $http.get('launcher.json')
.then(function(response) {
return response.data;
});
return {
LauncherTitle: LauncherTitle,
LauncherSlogan: LauncherSlogan
}
var data = response.data;
data.forEach(data.news, function(clientdata.news, index) {
angular.forEach(clientdata.news, function(newsitem, index){
$scope.news.push(newsitem);
});
});
}
})();
</script>
HTML
<div ng-app="myApp" ng-controller="myController">
<h1 class="display-3">{{ GameLauncherTitle }}</h1>
<h3 class="display-5">{{ GameLauncherSlogan }}</h3>
<div class="card-columns">
<div class="card" ng-repeat="newsitem in news">
<img src="{{ newsitem.FeaturesImage }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title text-dark">{{ newsitem.Title }}</h5>
<p class="card-text text-dark">{{ newsitem.Description }}</p>
</div>
</div>
</div>
</div>
But this isn't returning any results.
You are quitting out of your myController function with the two returns, I think you might have been trying
(function() {
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope, $http) {
$scope.news = []
$http.get('launcher.json')
.then(function(r) {return JSON.parse(r)})
.then(function(response) {
response.news.forEach(function(newsitem){
$scope.news.push(newsitem);
});
});
});
})();
Can you try this instead of your Angular Code?
Cleaned version:
(() => {
const myApp = angular.module('myApp', []);
myApp.controller('myController', ($scope, $http) => {
$scope.news = []
$http.get('launcher.json')
.then(r => JSON.parse(r))
.then(response => {
response.news.forEach(function (newsitem) {
$scope.news.push(newsitem);
})
})
})
})();

Creating Dynamic HTML using json data in reactjs

I have the below json data and the react code to populate the data dynamically
var DATA = [{"processList":
[{"processId":"1","processName":"Process1","htmlControlType":"radio","cssClassName":"radio"},
{"processId":"2","processName":"Process2","htmlControlType":"radio","cssClassName":"radio"}],
"processIndexList":
[{"processId":"1","indexId":"1","indexDesc":"First Name","htmlControlType":"textbox","cssClassName":"form-control"},{"indexId":"2","indexDesc":"Last Name","htmlControlType":"textbox","cssClassName":"form-control"}]}];
renderProcessList: function () {
const data = DATA;
return data[0].processList.map(group => {
return <div className={group.cssClassName}>
<label><input type={group.htmlControlType} name="processOptions"/>{group.processName}</label>
</div>
});
},
renderProcessData: function () {
const data = DATA;
return data[0].processIndexList.map(group => {
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
},
As of now the form is getting displayed based on the json data, but i want to display the form based on the user selection in the process list
ex: If the user select the Process1 radio the the First Name text box needs to be displayed below the radio and the user selects the process2 then Last Name text box needs to be displyed.
Can anyone tell me how to do it in reactjs?
To achieve the task, you have to implement the next three steps:
Handle radio input click.
Store the selected process ID in the state.
Display process list items, based on the selected ID (a.k.a. filtering).
Please note that you missed to add processId property in processIndexList[1] object.
Also please consider that in the example below I'm using basic filtering in renderProcessData().
I implemented the example in ES5, ES6 because of question's author request. Keep in mind that in the both examples I'm using JSX, so you need a compiler tool (Babel for example). Once you use a compiler, then you can use latest JS features. Please revise your choise of using ES5.
ES6
var DATA = [{
"processList": [{
"processId": "1",
"processName": "Process1",
"htmlControlType": "radio",
"cssClassName": "radio"
},
{
"processId": "2",
"processName": "Process2",
"htmlControlType": "radio",
"cssClassName": "radio"
}
],
"processIndexList": [{
"processId": "1",
"indexId": "1",
"indexDesc": "First Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}, {
"processId": "2",
"indexId": "2",
"indexDesc": "Last Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}]
}];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedProcessID: null
};
}
setProcessID(e) {
this.setState({
selectedProcessID: e.target.value
});
}
renderProcessList() {
const data = DATA;
return data[0].processList.map( group => {
return <div className={group.cssClassName}>
<label><input
value={group.processId}
onClick={this.setProcessID.bind(this)}
type={group.htmlControlType}
name="processOptions"/>{group.processName}</label>
</div>
});
}
renderProcessData() {
// Display process data, only if there is already
// selected process ID
if ( ! this.state.selectedProcessID) return;
const data = DATA;
return data[0].processIndexList.map( group => {
// Display process list items for the selected process ID.
// The filtering can be implemented performance better with a library (lodash for example).
// Current implementation is enough for the SO demo.
if (group.processId !== this.state.selectedProcessID) return;
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
}
render() {
return <div>
{this.renderProcessList()}
{this.renderProcessData()}
</div>
}
}
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
ES5
var DATA = [{
"processList": [{
"processId": "1",
"processName": "Process1",
"htmlControlType": "radio",
"cssClassName": "radio"
},
{
"processId": "2",
"processName": "Process2",
"htmlControlType": "radio",
"cssClassName": "radio"
}
],
"processIndexList": [{
"processId": "1",
"indexId": "1",
"indexDesc": "First Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}, {
"processId": "2",
"indexId": "2",
"indexDesc": "Last Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}]
}];
var App = React.createClass({
getInitialState() {
return {
selectedProcessID: null
}
},
setProcessID: function(e) {
this.setState({
selectedProcessID: e.target.value
});
},
renderProcessList: function() {
const data = DATA;
return data[0].processList.map( group => {
return <div className={group.cssClassName}>
<label><input
value={group.processId}
onClick={this.setProcessID.bind(this)}
type={group.htmlControlType}
name="processOptions"/>{group.processName}</label>
</div>
});
},
renderProcessData: function() {
// Display process data, only if there is already
// selected process ID
if ( ! this.state.selectedProcessID) return;
const data = DATA;
return data[0].processIndexList.map( group => {
// Display process list items for the selected process ID.
// The filtering can be implemented performance better with a library (lodash for example).
// Current implementation is enough for the SO demo.
if (group.processId !== this.state.selectedProcessID) return;
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
},
render: function() {
return <div>
{this.renderProcessList()}
{this.renderProcessData()}
</div>
}
});
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

Access nested objects in API using vue resource

I'm just starting out with vue resource (and ajax in general) and I'm having trouble listing an array that's nested in my API.
If this is my sample JSON:
{
"item1" : "data",
"item2" : 1234,
"item3" : 5678,
"item6" : "data",
"item7" : [ {
"id" : 0,
"data2" : "testdata",
"data3" : "testdata",
},{
"id" : 2,
"data2" : "testdata",
"data3" : "testdata",
},{
"id" : 3,
"data2" : "testdata",
"data3" : "testdata",
} ]
}
I want to pass the item7 array through a list in my html like this:
<div id="app">
<ul v-for="item in items">
<li>{{ item.data2 }} {{ item.data3 }}</li>
</ul>
</div>
Here's my js:
window.onload = function() {
new Vue({
el: '#app',
data: {
items: {}
},
ready: function () {
this.$http.get('/api/items', function(data) {
console.log(data);
this.items = data.item7[];
});
},
});
};
Naturally this returns nothing, I'm not sure how to loop the array through this.items = data.item7[]; with vue resource.
You just need to write this.items = data.item7, no need for [].
You also need to bind this to the function. When you're in the callback from the HTTP request, this refers to something else. So you can use .bind(this) like so:
this.$http.get('/api/items', function(data) {
this.items = data.item7;
}.bind(this));
Lastly, you should instantiate items as an array if it is going to be an array:
data: {
items: []
},

How to validate JSON data with ng-pattern

My app pulls json data and randomises the results on click, how can i validate each result that get's generated and state whether the value is valid/invalid?
view
<div ng-controller="idCtrl">
<button ng-click="randomize()">Random value on click</button>
<p>Id Number: <span data-ng-bind="RandomId.number"></span></p>
<p>Valid?: <span></span> </p>
</div>
json
[
{"number": "8607025402081"},
{"number": "8501016184086"},
{"number": "6104053425672"},
{"number": "8909025012083"},
{"number": "2222222222222"},
{"number": "8888888888888"},
{"number": "0000000000000"},
{"number": "9999999999999"}
]
script
var idApp = angular.module('idApp', []);
idApp.controller('idCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.regex = '(((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012]) (0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229))(( |-)(\d{4})( |-)(\d{3})|(\d{7}))';
$scope.randomize = function(){
$http.get('js/idnumbers.json')
.success(function(data) {
$scope.idnumber = data;
var randomIDIndex = Math.floor(Math.random() * $scope.idnumber.length);
$scope.RandomId = $scope.idnumber[randomIDIndex];
console.log(data);
})};
}]);
ngPattern is used with input controls most often. If you wanted to use ngPattern you could do something like the following. However, the invalid values are not being put in the text box. I assume this is because they are...invalid.
Note: I modified your regex from a string to a RegExp.
var idApp = angular.module('idApp', []);
idApp.controller('idCtrl', ['$scope', '$http',
function($scope, $http) {
var data = [{
"number": "8607025402081"
}, {
"number": "8501016184086"
}, {
"number": "6104053425672"
}, {
"number": "8909025012083"
}, {
"number": "2222222222222"
}, {
"number": "8888888888888"
}, {
"number": "0000000000000"
}, {
"number": "9999999999999"
}];
$scope.regex = /(((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012]) (0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229))(( |-)(\d{4})( |-)(\d{3})|(\d{7}))/;
$scope.randomize = function() {
//make your HTTP call here
$scope.idnumber = data;
var randomIDIndex = Math.floor(Math.random() * $scope.idnumber.length);
$scope.RandomId = $scope.idnumber[randomIDIndex];
console.log($scope.form.theInput.$valid);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="idApp">
<div ng-controller="idCtrl">
<form name="form">
<button ng-click="randomize()">Random value on click</button>
<p>Id Number: <input name="theInput" ng-pattern="regex" ng-model="RandomId.number"></input></p>
<p>Valid?: <span>{{form.theInput.$valid}}</span> </p>
</form>
</div>
</div>
Since ngPattern is limited to input boxes you may want to just use good ol' JavaScript to accomplish the validation. E.g.,
var idApp = angular.module('idApp', []);
idApp.controller('idCtrl', ['$scope', '$http',
function($scope, $http) {
var data = [{
"number": "8607025402081"
}, {
"number": "8501016184086"
}, {
"number": "6104053425672"
}, {
"number": "8909025012083"
}, {
"number": "2222222222222"
}, {
"number": "8888888888888"
}, {
"number": "0000000000000"
}, {
"number": "9999999999999"
}];
var regex = /(((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012]) (0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229))(( |-)(\d{4})( |-)(\d{3})|(\d{7}))/;
$scope.randomize = function() {
//http call here
$scope.idnumber = data;
var randomIDIndex = Math.floor(Math.random() * $scope.idnumber.length);
$scope.RandomId = $scope.idnumber[randomIDIndex];
$scope.valid = regex.test($scope.RandomId.number);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="idApp">
<div ng-controller="idCtrl">
<button ng-click="randomize()">Random value on click</button>
<p>Id Number: <span data-ng-bind="RandomId.number"></span>
</p>
<p>Valid?: {{valid}}
</p>
</div>
</div>

Template not work with Backbone and Handlebars

Here I have problem to render my template with handlebars and backbone.
I don't know why my each block doesn't work.
I rewrite my template several times and my json but it never work.
If someone have an idea of where my mistake here :)
here my index.html:
<body>
<div id="page">
</div>
<script type="text/x-handlebars-template" id="template">
<h4> test template </h4>
{{#each rappers}}
<p>{{rappers.blazz}} !!!!!!</p>
{{/each}}
</script>
</body>
I got this result :
test template
!!!!!!
!!!!!!
!!!!!!
but not the {{blazz}} value ..
here my js:
var Rapper = Backbone.Model.extend({
// defaults : {
// blazz: ""
// },
initialize: function() {
console.log("Création d'un nouveau rapper");
}
})
var Rappers = Backbone.Collection.extend({
// defaults : {
// blazz: "pas de blazz"
// },
model : Rapper,
url : './js/data.json'
})
var RapperList = Backbone.View.extend({
el:'#page',
render: function(){
var that = this;
var rappers = new Rappers();
rappers.fetch({
success: function(rappers){
var source = $("#template").html();
var template = Handlebars.compile(source);
that.$el.html(template({rappers : rappers.toJSON()}));
}
})
}
});
var Router = Backbone.Router.extend({
routes:{
'' : 'home'
}
});
var rapperList = new RapperList();
var router = new Router();
router.on('route:home',function(){
rapperList.render();
})
Backbone.history.start();
And my JSON:
[
{"rapper" :
[
{"blazz" : "person1"},
{"nom" : "paul"},
]
},
{"rapper" :
[
{"blazz" : "person2"},
{"nom" : "mike"},
]
},
{"rapper" :
[
{"blazz" : "person3"},
{"nom" : "jean"},
]
}
]
Can you try this:
<body>
<div id="page">
</div>
<script type="text/x-handlebars-template" id="template">
<h4> test template </h4>
{{#each rappers}}
<p>{{blazz}} !!!!!!</p>
{{/each}}
</script>
</body>
By using directly {{blazz} and not {{rappers.blazz}
Here my solution :
I slightly change the shape of the code. (and added a few more items in).
So here the new JSON :
[
{
"blazz" : "blazz1",
"prenom" : "prenom1",
"age" : 20,
"album" :
[
{
"nom" : "album1",
"vente" : 1000}
,
{
"nom" : "album2",
"vente" : 10068
}
]
},
{
"blazz" : "blazz2",
"prenom" : "prenom2",
"age" : 15,
"album" :
[
{
"nom" : "album1",
"vente" : 1000}
,
{
"nom" : "album2",
"vente" : 108798
}
]
},
{
"blazz" : "blazz3",
"prenom" : "prenom3",
"age" : 35,
"album" :
[
{
"nom" : "album1",
"vente" : 6546
}
,
{
"nom" : "album2",
"vente" : 4816
}
]
}
]
and here the new template :
{{#each rappers}}
<p>blazz: {{blazz}} prenom: {{prenom}} nom: {{nom}}</p>
<ul>
{{#each this.album}}
<li>nom: {{nom}}</li>
{{/each}}
</ul>
{{/each}}
The difference is here :
Before :
{"object" :
[
{"foo" : "content"},
{"foo" : "content"}
]
}
And after
{"object" :
[
{"foo" : "content",
"foo" : "content"}
]
}