How to modify a JSON value in a file using NodeJS - javascript

I have created a drop down menu for people to edit the location. And all contents are generated by for loop, how may i depends on the feedID to change the region, because the $.post() funcion would change all region but not depends on it's feedID at the moment.
<span class="dropdown">
<span class="result-date" type="button" data-toggle="dropdown">Hong Kong
<span class="caret"></span>
</span>
<ul class="dropdown-menu">
<li id="CTHK">Hong Kong</li>
<li id="CTTW">Taiwan</li><
<li id="CTMA">Macau</li><
<li id="CTCN">China</li><
<li id="CTOT">Others</li>
</ul>
</span>
After the users have made decision of the modification and click on the desire option, it will trigger a $.post() function in order to change the JSON's content via speicifc api
var initRegionEdit = function() {
$("#CTHK").click(function() {
var api = "/domain/path/somemorepaths?id=" + id;
var postData = {
region : "TW"
};
$.post(api_submit, postData).done(function (data) {
console.log(postData)
});
})
}
And afterward it will get into an JSON file and change the region section
"errorCode": null,
"message": "Success",
"result": {
"total": 2,
"data": [
{
"title": "watever",
"content": " lietlie siktl i's fgkkksfsag...",
"region": "Hong Kong",
"feedId": "dfc68cff0a2afc540407d02f554d9508",
},
{
"title": "Visual F",
"content": "STORE \" I'm ...",
"region": "Hong Kong",
"feedId": "e54de354837e3add77b1030e5456e522",
}
how may i depends on the feedID to change the the region?
UPDATE 1:
Let's assume the user click on others ,The outcome I'd like to see is like when the user click on the .section defined by a feedId.
<div class="dfc68cff0a2afc540407d02f554d9508"> //generate by {{feedId}} handle bar js
<span class="dropdown">
<span class="result-date" type="button" data-toggle="dropdown">Hong Kong
<span class="caret"></span>
</span>
<ul class="dropdown-menu">
<li id="CTHK">Hong Kong</li>
<li id="CTTW">Taiwan</li><
<li id="CTMA">Macau</li><
<li id="CTCN">China</li><
<li id="CTOT">Others</li>
</ul>
</span>
</div>
and the javascript api should change the feedId match the section instead of every json's region
{
"title": "Visual F",
"content": "STORE \" I'm ...",
"region": "Others",
"feedId": "e54de354837e3add77b1030e5456e522",
}
P.S I am developing the application by node.js

A solution based on the following procedure:
Reading file -> modifying its contents -> write file would be to use the File System Node Module
Example code:
var fs = require('fs');
// Read file and parse into JSON
var jsonFileObject = JSON.parse(fs.readFileSync('fileName'));
... modify the contents of jsonFileObject as required
// Write the modified contents back to the file
var jsonFileObject = JSON.parse(fs.writeFileSync('fileName', jsonFileObject));
To modify the region based on the feedId in your particular example:
for (var dataIndex in jsonFileObject.result.data) {
if (jsonFileObject.result.data[dataIndex].feedId === feedId) {
jsonFileObject.result.data[dataIndex].region = updatedRegion;
}
}
assuming the JSON file has the same format as your post. If not, it should be fairly straightforward to modify the example to meet your needs.

Related

How to display paging results using paging id using ngx-datatable & angular?

Requirement:
Showing dynamic data using ngx-datatable and use paging using page id
Description :
I have a dynamic data where I am displaying it using the ngx-datatable in angular and here everything works but the issue I m not sure how to apply the paging using the page_id (sent to the server using post body). Here I am getting the page_id along with the API response this is 1st API call. here page_id has to be sent as a body for the very same API for getting the rest of results.
Ex: Suppose I have 20 results in the 1ST API call I will get the 10 records and a page id by using the page id how can I get the next 10 results
What I implemented:
Getting data and displaying it in table basic paging applied
Below is my code :
Result=[];
reorderable: boolean = true;
selected = [];
rows = [];
columns = [];
DataArray = [];
Results = {
"data": [
{
"_score": 0.36464313,
"_type": "data",
"_id": "abcd",
"_source": {
"filter": "data",
"information": {
"product_id": "abcd",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "dell_laptop"
},
{
"_score": 0.36464314,
"_type": "data",
"_id": "abcde",
"_source": {
"filter": "data",
"information": {
"product_id": "abcde",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "lenovo_laptop"
},
{
"_score": 0.36464314,
"_type": "data",
"_id": "abcdef",
"_source": {
"filter": "data",
"information": {
"product_id": "abcde",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "lenovo_laptop"
}
],
"total": 4,
"page_id": "WpNdVJMMjlJVnJTYTFuUklB"
}
LoadInfo(){
this.DataArray = ["filter","information.product_id","information.creation_utctime","enduser"];
this.rows=[];
this.Result = this.Results['data'];
// tslint:disable-next-line: forin
for (var res in this.Result) {
var row = {};
for (var key in this.Result[res]['_source']) {
if (typeof this.Result[res]['_source'][key] === 'object') {
for (var k in this.Result[res]['_source'][key]) {
let temp = key + "." + k;
row[temp] = this.Result[res]['_source'][key][k];
}
} else {
row[key] = this.Result[res]['_source'][key]
}
row['_id'] = this.Result[res]['_id'];
}
this.rows.push(row);
}
console.log(this.rows);
}
onActivate(event) {
// console.log('Activate Event', event);
}
onSelect({ selected }) {
// console.log('Select Event', selected, this.selected);
this.selected.splice(0, this.selected.length);
this.selected.push(...selected);
}
HTML Code:
<button type="button" (click)="LoadInfo()">LoadData</button>
<div>
<ngx-datatable class="material ui" [rows]="rows" [columnMode]="'force'" [headerHeight]="50"
[footerHeight]="50" [limit]="2" [rowHeight]="'auto'" [reorderable]="reorderable" [selected]="selected"
[selectionType]="'checkbox'" [scrollbarH]="true" [sortType]="'multi'" (activate)="onActivate($event)"
(select)='onSelect($event)'>
<ngx-datatable-column [width]="30" [sortable]="true" [canAutoResize]="false" [draggable]="false"
[resizeable]="false" class="uih">
<ng-template ngx-datatable-header-template let-value="value" let-allRowsSelected="allRowsSelected"
let-selectFn="selectFn">
<input type="checkbox" [checked]="allRowsSelected" (change)="selectFn(!allRowsSelected)" />
</ng-template>
<ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected"
let-onCheckboxChangeFn="onCheckboxChangeFn">
<input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" />
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column *ngFor="let attr of DataArray" [sortable]="true" prop={{attr}} name={{attr}}>
</ngx-datatable-column>
</ngx-datatable>
</div>
Stackblitz link: https://stackblitz.com/edit/angular-secw8u
Note: even though if there is pageid also some times after 10 records there may not be more records also
here api call is simple post request
api : https://xxxx.xxxx..com/<some method>
body: { "key1":"data1","key2":"data2","pageid":"ss"}
here in the first api call we wont send page id as after calling the first api call we will get response in that we will get the pageid and for the second api call i mean for paging then we have to use the pageid
For pagination you need to know total number of pages. Otherwise you need total number
of items along with number of items per page (to derive total number of pages). In your case
you only have a page-id which does not even say the which page you are on. The page-id
only gives you access to next page items.
This API is useful if you implement an infinite scroll feature. Otherwise you can only
implement a more button to which loads new items to table. The link
you provided in comments implements this more button feature.
So you can override the default footer of ngx-datatable to add your more button to load
more items to table.
<ngx-datatable-footer>
<ng-template ngx-datatable-footer-template
let-rowCount="rowCount"
let-pageSize="pageSize"
let-selectedCount="selectedCount"
let-curPage="curPage"
let-offset="offset"
let-isVisible="isVisible">
<div class="datatable-footer-inner selected-count">
<div class="page-count" *ngIf="selectedCount">
<span> {{selectedCount}} selected / </span> {{rowCount}} total
</div>
<div class="datatable-pager">
<ul class="pager">
<li class="pages active" role="button" aria-label="next" *ngIf="rowCount">
Next
</li>
</ul>
</div>
</div>
</ng-template>
</ngx-datatable-footer>
Stackblitz Demo

reference a json field name that contains a dot

I am trying to reference a field from the JSON in Angular
{ "elements": [
{
"LCSSEASON.IDA2A2": "351453",
"LCSSEASON.BRANCHIDITERATIONINFO": "335697"
},
{
"LCSSEASON.IDA2A2": "353995",
"LCSSEASON.BRANCHIDITERATIONINFO": "298931"
},
{
"LCSSEASON.IDA2A2": "310935",
"LCSSEASON.BRANCHIDITERATIONINFO": "282654"
},
{
"LCSSEASON.IDA2A2": "353967",
"LCSSEASON.BRANCHIDITERATIONINFO": "353966"
},
{
"LCSSEASON.IDA2A2": "355294",
"LCSSEASON.BRANCHIDITERATIONINFO": "355293"
}
]
}
In the HTML Template, I want to print the element - elements.LCSSEASON.IDA2A2
But having 2 dots in key is causing issues in below code
Any ideas and suggestions??
I cannot change server JSON Output as its legacy application and I have no control.
<ul *ngFor="let item of items"> <li> {{item.LCSSEASON.IDA2A2}} </li> </ul>
access the property using square brackets like this
<ul *ngFor="let item of items"> <li> {{item['LCSSEASON.IDA2A2']}} </li> </ul>

pass data via on-click angularjs

I have a .json file with a list of cows with details about where each one lives.
I have two panels.
One panel displays the list of cows and I have this displayed using ng-repeat.
The second panel appears when the title of the cow is clicked on, which is all great and working. However I can't seam to work out how to pass the location of that particular cow. Is it possible to pass grab and pass the number in the cow array? I've tried passing {{'cow'}} thinking that this would represent the array id but I don't think I'm on the right track so thought I'd post up here.
Is there any way to pass the data so that only the location of the cow clicked shows up? Do I need to call a promise or something?
Thanks - code below of where I am so far
HTML
<html ng-app="animalApp">
<section ng-controller="AnimalController as animalCtrl">
<ul ng-controller="PanelController as panel">
<li ng-class="{ active: panel.isSelected(1)}" ng-show="panel.isSelected(1)">
<ul>
<li ng-repeat="cow in animalCtrl.cows">
<h2>
</h2>
</li>
</ul>
</li>
<li ng-class="{ active: panel.isSelected(2)}" ng-show="panel.isSelected(2)">
<p>This {{animalCtrl.cow.name}} lives in {{animalCtrl.cow.country}}</p>
Back to all cows
</li>
</ul>
</section>
</html>
JS
var app = angular.module('animalApp', [ ]);
app.controller('AnimalController', ['$http', '$scope',function($http, $scope){
var type = this;
type.cows = [ ];
$http.get('animals.json').success(function(data){
type.cows = data;
});
app.controller("PanelController", function() {
this.tab = 1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelected = function(checkTab) {
return this.tab === checkTab;
}
});
JSON
[
{
"name": "Angus",
"country": "UK"
},
{
"name": "Hereford",
"country": "Canada"
},
{
"name": "Dwarf Lulu",
"country": "Nepal"
},
{
"name": "Ongole",
"country": "India"
}
]
Here is a PLUNKER with the additions from the submitted answers(thanks) but yet to still get it to work. When clicking on 'Angus UK. I'm aiming to have the paragraph say 'This Angus lives in UK' - which is currently does not. Thanks again for the help.
You can just pass in cow. Based on your code, this seems to be what you want.
<li ng-repeat="cow in animalCtrl.cows">
<h2>
</h2>
</li>
controller
app.controller('AnimalController', ['$http', '$scope',function($http, $scope){
var type = this;
type.cows = [ ];
$http.get('animals.json').success(function(data){
type.cows = data;
});
type.cowId = function(cow){
this.cow = cow;
};
}
or if you wanted to pass in the index of the iterated cow
<li ng-repeat="cow in animalCtrl.cows">
<h2>
</h2>
</li>
controller
app.controller('AnimalController', ['$http', '$scope',function($http, $scope){
var type = this;
type.cows = [ ];
$http.get('animals.json').success(function(data){
type.cows = data;
});
type.cowId = function(id){
this.cow = type.cows[id];
};
}
Plunkr

Create a form and add Data throw Angular js but not added?

I m created a new form in my listing and created a form if i fill the data in form and than click to submit button but my data in not added in filled show .
Can u help me please i m new in angular js
My code is here
Angular Js is
// Code goes here
var myAppMy = angular.module('myFapp', []);
myAppMy.controller('myControler', function($scope) {
$scope.items = [{
"title": "Book",
"subtitle": [{
"subtitle": "PanchTantra ",
"description": "Kids Books",
"authorName": "Kisna"
}],
"description": "Some Book is very Good."
}, {
"title": "Mediciane Book",
"subtitle": [{
"subtitle": "Pharmacy",
"description": "This book is related to Docotrs"
}],
"description": "This book is very hard"
}, {
"title": "Reciape Book",
"subtitle": [{
"subtitle": "Khana Khajana",
"description": "This book is related to Foods"
}],
"description": "This book is nice..."
}, {
"title": "Computer Book",
"subtitle": [{
"subtitle": "BCA MCA",
"description": "This book is related to Education"
}],
"description": "This book is very beautiful."
}
];
$scope.addnewFormData = function(subtitle, description) {
if (this.addNewText === '') return;
$scope.items.subtitle.push({
subtitle: subtitle,
description: description
});
}
});
HTML COde is
<body ng-app="myFapp">
<ul ng-controller="myControler">
<li ng-repeat="item in items">
<div>{{item.title}}</div>
<div>{{item.description}}</div>
<ul>
<li ng-repeat="subtitle in item.subtitle">
<div>{{subtitle.subtitle }}
<a ng-show="subtitle.authorName" href="#">
<img src="https://www.gravatar.com/avatar/76e03db06bb6dcf24f95bf4d354486db?s=32&d=identicon&r=PG" />{{ subtitle.authorName}}</a>
</div>
<div>{{subtitle.description}} this is</div>
</li>
<li>
<form ng-submit="addnewFormData(addNewText, addBookDescription)">
<input type="text" ng-model="addNewText" placeholder="Enter Book Name" />
<input type="text" ng-model="addBookDescription" placeholder=" Enter Book Description here ..." />
<input type="submit" value="submit" />
</form>
</li>
</ul>
</li>
</ul>
</body>
Plunkr link
in your addnewFormData you are trying to access subtitle field from items array, but you need to access to it from current item
the easiest solution is to add third parameter to addnewFormData and pass current item to it, since actually you have many forms one for each item, and that function doesn't know which item to access.
Something like
$scope.addnewFormData = function(item, subtitle, description){
if(this.addNewText === '') return ;
item.subtitle.push({
subtitle:subtitle,
description:description
});
}
and in html:
<form ng-submit="addnewFormData(item, addNewText, addBookDescription)">
from the docs:
In Angular forms can be nested. This means that the outer form is valid when all of the child forms are valid as well. However, browsers do not allow nesting of elements, so Angular provides the ngForm directive which behaves identically to but can be nested. This allows you to have nested forms, which is very useful when using Angular validation directives in forms that are dynamically generated using the ngRepeat directive. Since you cannot dynamically generate the name attribute of input elements using interpolation, you have to wrap each set of repeated inputs in an ngForm directive and nest these in an outer form element.
https://docs.angularjs.org/api/ng/directive/form

advice about how I can combine 2 Handlebars templates that both use the same data?

I'm currently learning how to template using Handlebars and would like some advice about how I would combine the following 2 templates into 1 and update my script so each button still displays the correct set of values?
Templates
<script type="text/x-handlebars" id="infoTemp">
{{#each films}}
<li>
<h2>{{title}}</h2>
<p>{{{description}}}</p>
</li>
{{/each}}
</script>
<script type="text/x-handlebars" id="additionalInfoTemp">
{{#each films}}
<li>
<h1>{{id}}</h1>
<h2>{{title}}</h2>
<p>{{{description}}}</p>
<small>{{released}}</small>
</li>
{{/each}}
</script>
JS
// Dummy data
data = {
"films": [
{
"id": "1",
"title": "The Shawshank Redemption",
"description": "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.",
"released": "2012-09-17 00:00:00"
},
{
"id": "2",
"title": "The Godfather",
"description": "The aging <b>patriarch of an organized</b> crime dynasty transfers control of his clandestine empire to his reluctant son.",
"released": "2012-09-17 00:00:00"
}
]
}
var $info = $('#info');
var source;
//Grab contents of template
function templateData(id){
if( id == 'add1' ){
source = $("#infoTemp").html();
} else {
source = $("#additionalInfoTemp").html();
}
var template = Handlebars.compile(source);
$info.append(template(data));
}
//Grab the container div and insert the templated data in
$('button').on('click', function(e){
var thisData = $(this).data('id');
$info.html('');
templateData(thisData);
e.preventDefault();
});
JS Fiddle
http://jsfiddle.net/2TpJh/2/
​
You can check for the existence of each of the variables and render the h1 and released only if they exist:
<script type="text/x-handlebars" id="additionalInfoTemp">
{{#each films}}
<li>
{{#id}}<h1>{{.}}</h1>{{/id}}
<h2>{{title}}</h2>
<p>{{{description}}}</p>
{{#released}}<small>{{.}}</small>{{/released}}
</li>
{{/each}}
</script>

Categories