Fetch URI from Post Data through Get Data - json

Show 1 textfield with 2 buttons - Post, Get. Take a number as input in a text field. On clicking Post, create an array of the numbers from 1 to that number. Post this array at the URL. Display the response from the Post.On clicking Get, fetch data from the URL returned by the Post and display it.
urlPost = 'https://api.myjson.com/bins';
clist: number[] = [];
strData: string = '';
S1: String = '';
ntext: number;
constructor(private netService: NetService) {}
postData() {
for (var i = 1; i <= this.ntext; i++) {
this.clist.push(i);
}
this.netService.postData(this.urlPost, this.clist)
.subscribe(postresp => {
this.strData = JSON.stringify(postresp);
});
}
getData() {
this.netService.getData(this.strData.Uri)
.subscribe(resp => {
this.strData = JSON.stringify(resp);
});
}
this line need to be improved.
this.netService.getData(this.strData.Uri)

As I understand your question, you simply have a problem with parsing a response from your postData(). So, just refer to the following -
postData() {
for (var i = 1; i <= this.ntext; i++) {
this.clist.push(i);
}
this.netService.postData(this.urlPost, this.clist)
.subscribe(postresp => {
this.S1 = postresp['uri']; // get URL here
});
}
getData() {
this.netService.getData(this.S1) // use it here
.subscribe(resp => {
this.strData = JSON.stringify(resp);
});
}
See it working here.

Related

How To Put A Number In Front Of Every Suggestion Corretcly?

Detail Of The Problem
As title, I am using Google App Script and Google Docs API's Batchupdate, trying to put number in front of every suggestion. However, I can place it correctly at the very first one, but it starts to deviate after the first one.
Result I Currently Have
Please refer to the image below.
What I have Tried
Below is the snippet I currently have
function markNumberInFrontOfMark(fileID) {
fileID = "MYFILEID";
let doc = Docs.Documents.get(fileID);
let requests = doc.body.content.flatMap(content => {
if (content.paragraph) {
let elements = content.paragraph.elements;
return elements.flatMap(element => element.textRun.suggestedDeletionIds ? {
insertText: {
text: "(1)",
location: {
index: element.startIndex
}
}
} : []);
}
return [];
});
Docs.Documents.batchUpdate({requests}, fileID);
return true;
}
Result I Want To Have
Please refer to the image below
Post I Refer to
How to change the text based on suggestions through GAS and Google DOC API
Here is an example of how to insert text. In this case I am adding 3 characters "(1)" for example. If the number of additions exceeds 9 you will have to adjust the number of characters added.
function markNumberInFrontOfMark() {
try {
let doc = DocumentApp.getActiveDocument();
let id = doc.getId();
doc = Docs.Documents.get(id);
let contents = doc.body.content;
let requests = [];
let num = 0;
contents.forEach( content => {
if( content.paragraph ) {
let elements = content.paragraph.elements;
elements.forEach( element => {
if( element.textRun.suggestedDeletionIds ) {
num++;
let text = "("+num+")"
let request = { insertText: { text, location: { index: element.startIndex+3*(num-1) } } };
requests.push(request);
}
}
);
}
}
);
if( requests.length > 0 ) {
Docs.Documents.batchUpdate({requests}, id);
}
}
catch(err) {
console.log(err)
}
}
And the resulting updated document.

Access a nested JSON object property via a single string

This line: let X = this.appGlobal.GetNavigationLanguage().data;
retuns JSON as you can see below.
I want to take NAV.REPORTS.BMAIL.TITLE.
Translate code (NAV.REPORTS.BMAIL.TITLE) is dynamically created.
X.NAV.REPORTS.BMAIL.TITLE => works
X['NAV']['REPORTS']['BMAIL']['TITLE'] => works
But keep in mind I have dynamically created translation code I need something like this:
let transCode = 'NAV.REPORTS.BMAIL.TITLE';
console.log(X[transCode]);
How I can achieve this?
test_data = {
NAV: {
REPORTS: {
BMAIL: {
TITLE: "hello"
}
}
}
}
let transCode = 'NAV.REPORTS.BMAIL.TITLE';
properties = transCode.split('.'); //--> ["NAV","REPORTS","BMAIL","TITLE"]
result = test_data
properties.forEach(function(property) {
result = result[property]
})
console.log(result) // --> hello
The short and evil route would be the following:
console.log(eval(`X.${transCode}`));
The less evil way is to use a recursive function call, this means you only look into the number of items in your string-path (rather than looping the whole collection).
const X = {
NAV: {
REPORTS: {
BMAIL: {
TITLE: 'Test'
}
}
}
}
const transCode = 'NAV.REPORTS.BMAIL.TITLE';
// Evil...
console.log(eval(`X.${transCode}`)); // Test
// Less Evil (but needs exception handling)...
function getData(input: any, splitPath: string[]) {
const level = splitPath.pop();
if (splitPath.length === 0) {
return input[level];
} else {
return getData(input[level], splitPath);
}
}
const result = getData(X, transCode.split('.').reverse());
console.log(result); // Test

How to wait to finish subscribe before moving to next index in for loop in Angular 6

I'm using Angular 6.
I have an array of links and a variable to store fetched information in same order as of array one by one.
Here is what I'm trying to do using for loop.
products: any;
processedItems: Array<any> = [];
private _processItem() {
for (let i = 0; i < this.products.length; i++) {
this.scraperService.scrapSingle(this.products[i].url).subscribe(
res => {
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = this.products[i];
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
}
);
}
console.log(this.products.length);
}
But how to wait for subscribe before moving to next index in the loop?
Just splice the p_item into your array at the required index given i.
For example instead of doing,
this.processedItems.push(p_item);
do this,
this.processedItems.splice(p_item, 0, i);
That solves your problem :)
Use promises instead of rx.js subscriptions via using toPromise method. You might need to map the res to json. res.map(item => item.json());
products: any;
processedItems: Array < any > =[];
private _processItem() {
this.products.array.forEach(async (element) => {
const res = await this.scraperService.scrapSingle(element.url).toPromise();
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = element
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
});
console.log(this.products.length);
}

Object from Observable then Array from Observable inside a foreach. how to order it?Asynchronous Angular 4/5

Here is my problem.
I'm running a method that sends me a json (method = myTableService.getAllTables ()), to create an object (object = this.myTables).
Then I execute the method for each, for each element of this.myTables I execute a new request (request = this.myTableService.getTableStatut (element.theId)).
I retrieve data from a new json to create an object (object = myTableModel).
Each result will be added to this.myTableListProvisory.
The problem is the order of execution.
It execute the console.log before the end of the for each...
This.myTableListProvisory.length and this.myTableList.length return 0.
How to wait for the end of the for each run before running the console.log?
Thank you
ngOnInit() {
this.myTableService.getAllTables()
.subscribe(data => {
this.myTables = data;
this.myTableList = this.getAllTableStatut(this.myTables);
console.log("this.myTableList.length : " + this.myTableList.length);
}, err => {
console.log(err);
})
}
getAllTableStatut(myTables: any) {
this.myTableListProvisoire = [];
myTables.forEach(element => {
this.myTableService.getTableStatut(element.theId)
.subscribe(data => {
this.statut = data;
this.myTableModel = new MyTableModel(element.tableNumber, this.statut.name, element.theId);
this.myTableListProvisoire.push(this.myTableModel);
})
console.log("this.myTableListProvisoire.length : " + this.myTableListProvisoire.length);
})
return this.myTableListProvisoire;
}
Result of console.log
this.myTableListProvisoire.length : 0
this.myTableList.length : 0
UPDATE
I have simplified the code ... I put it in its entirety for the understanding. What I need is to sort the array after it is done. The problem is that I don't know how to use a flatMap method in a query inside a foreach ... I have temporarily placed the sort method inside the subscribe which is a bad solution for the performance. That's why I want to do my sort after the creation of the array. Thank you
export class MyTableComponent implements OnInit {
myTables: any;
statut: any;
myTableModel: MyTableModel;
myTableList: Array<MyTableModel>;
myTableListProvisoire: Array<MyTableModel>;
i: number;
j: number;
myTableModelProvisoire: MyTableModel = null;
constructor(public myTableService: MyTableService) { }
ngOnInit() {
this.myTableService.getAllTables()
.subscribe(data => {
this.myTables = data;
this.myTableList = this.getAllTableStatut(this.myTables);
}, err => {
console.log(err);
})
}
getAllTableStatut(myTables: any) {
this.myTableListProvisoire = [];
myTables.forEach(element => {
this.myTableService.getTableStatut(element.theId)
.subscribe(data => {
this.statut = data;
this.myTableModel = new MyTableModel(element.tableNumber, this.statut.name, element.theId);
this.myTableListProvisoire.push(this.myTableModel);
for (this.j = 0; this.j < this.myTableListProvisoire.length; this.j++) {
for (this.i = 0; this.i < this.myTableListProvisoire.length - 1; this.i++) {
if (this.myTableListProvisoire[this.i].getTableNumber() > this.myTableListProvisoire[(this.i + 1)].getTableNumber()) {
this.myTableModelProvisoire = this.myTableListProvisoire[this.i];
this.myTableListProvisoire[this.i] = this.myTableListProvisoire[(this.i + 1)];
this.myTableListProvisoire[(this.i + 1)] = this.myTableModelProvisoire;
}
}
}
}, err => {
console.log(err);
})
}, err => {
console.log(err);
})
return this.myTableListProvisoire;
}
}
Well Observables are asynchronous actions and will be executed after finishing the current execution block. So when the js engine comes to your
this.myTableService.getTableStatut(element.theId)
.subscribe(data => {
this.statut = data;
this.myTableModel = new MyTableModel(element.tableNumber, this.statut.name, element.theId);
this.myTableListProvisoire.push(this.myTableModel);
})
it will only create a subscription, but the code inside of it will be executed after all the other code in the block. So that's why your console.log is being executed before you get any data. So you need to place it inside the .subscribe block to see the. I think there can be a better solution to get the data, but I don't know the structure of the app, so I can't advice. If you create an example on https://stackblitz.com/ I could probably help you out with a better solution.

Display only the first elements of Object.keys

I have made a JSON Request so i can bring the Objects in Angular2. But I want to display only the first 15 elements and then if it works repeat the same process on InfiniteScroll. So this is one of my code.
setList(informes) {
if (informes) {
for (let id of Object.keys(informes)){
this.count = 0;
for (let i = 0; i < 15; i++) {
let node = informes[id];
this.informes.push(node[this.count]);
console.log (id);
this.count++;
}
}
}
}
Obviously It doesn't work, it keeps giving me all elements like 15 times each. I know that but on the other hand if i make the opposite.
setList(informes) {
if (informes) {
for (let i = 0; i < 15; i++) {
for (let id of Object.keys(informes)){
let node = informes[id];
this.informes.push(node[this.count]);
console.log (id);
}
this.count++
}
}
}
It counts the number of nodes in total.
What i want is to display only the first 15 elements. And then repeat the code in my other function infiniteScroll (I will do that by myself, it works).
Any suggestion will be appreciated.
UPDATE:
Here's the constructor:
constructor(public navCtrl: NavController, public navParams: NavParams, public nav: NavController, public http: Http, public sanitizer: DomSanitizer) {
this.dataUrl = 'https://myurl.com/ionic/'; //example
if (this.dataUrl) {
this.http.get(this.dataUrl)
.map(res => res.json())
.subscribe(informes => this.setList(informes));
}
}
UPDATE 2:
The code works well.
I had to modify some things to make it work. I will update the script so if it could help someone.
setList(informes) {
if (informes) {
let ids = Object.keys(informes);
ids.forEach((id, index) => {
if(index < 15){
let node = informes[id];
this.informes.push(node);
this.count++;
console.log(this.count);
}
});
}
}
goToNodeInformes(node){
this.navCtrl.push(NodeInformesPage, {'node':node.nid});
}
doInfinite(infiniteScroll, informes) {
informes = this.informes;
setTimeout(() => {
let ids = Object.keys(informes);
ids.forEach((id, index) => {
if(index < 15){
let node = informes[id];
this.informes.push(node);
this.count++;
console.log(this.count);
}
});
infiniteScroll.complete();
}, 500);
}
}
I will figure what i have to do for not repeating the same nodes (will update) but the counter works!!!
I think you are looking for something like this :
let keys = Object.keys(informes);
keys.foreach((key, index) => {
if(index < 15){
let node = informes[key];
this.informes.push(node);
console.log(informes[key]);
}
});