AngularJS display object in HTML - angularjs

i've made an api call to retrieve some data. succesfully.
It;s a sum of total hours of credits..i retrieve
Laravel SQL query:
$result = DB::table('contracts')
->select(DB::raw('SUM(monthly_credits) as Total'))
->get();
return $this->sendResponse($result->toArray(), 'credits retrieved succesfully');
Angular call:
monthlyCredits() {
return new Promise(resolve => {
this.http.get(this.apiUrl+'/api/credits').subscribe(data => {
resolve(data);},
err => {
console.log(err);
});
});
}
home.ts:
monthlyCredits(){
this.restProvider.monthlyCredits()
.then(data => {
this.credits = data['data'];
console.log(this.credits);
});
}
data: [{total: 50.5}]
-> 0: {total: 50.5}
As i display it on the frond-end with {{credits | json }}
it returns
[{"total":50.5}]
Im trying to only display the sum of the total credits, which is 50.5. not the other characters.
Thanks in advance.

You need to access the total property from the credits, change it as follows,
{{credits[0].total}}

You have to set the total to your this.credits or you have to use the fullpath within your html template like {{credits[0].total}}
try following in your home.ts:
monthlyCredits(){
this.restProvider.monthlyCredits()
.then(data => {
this.credits = data['data'][0]['total'];
console.log(this.credits);
});
Make sure you access total only if it is loaded.

Related

i need to access a POST request Response and that Response is An array of SearchSample objects Angular

The Function in my Component :
searchWithNyckel(){
const formData = new FormData();
formData.append('image', this.updateFormGroup.get('updateProduct.image').value);
this.productService.searchProductNyckel(formData).subscribe(
data => {
this.resForSearch= data
console.log(JSON.stringify(this.resForSearch));
// this.resForSearch.values()
}
)
}
The Function in my service :
searchProductNyckel(formData: FormData):Observable<SearchRes[]> {
const url = `https://www.nyckel.com/v0.9/functions/1wx5f2474e1ntc/search`
return this.httpClient.post<SearchRes[]>(url,formData);
}
The Console Response :
{
"searchSamples":
[{
"sampleId": "<sampleId>",
"distance": 0.86,
"externalId": "<externalId>"
}]
}
I NEED TO GET THE VALUE OF sampleId and distance
You can access the content of the response by using a map operator.
for instance:
this.productService.searchProductNyckel(formData).pipe(
map (response => response.searchSamples)
).subscribe((samples => console.log(sample))
will output the array of samples.
If you just want to access 1 variable of the 1st item of the array, you can use:
this.productService.searchProductNyckel(formData).pipe(
map (response => response.searchSamples[0].sampleId)
).subscribe((id => console.log(id))

Retrieve collection + subcollection give me an empty render

The problem
At web app startup, the main task is to retrieve all user informations that are stored in various Firestore's collections and sub-collections.
The problem is that, even if I uses promises and a Loading State to prevent an empty app rendering, the app is rendered with all collections data, except for collections that have sub-collections.
The process
- If user is logged
-- Set Loading Status Active
-- Load Collection A
-- Load Collection B and forEach, load all sub-collection
-- Load Collection C
-- Set Loading Status Inactive
At this point, the app is rendered, but only with Collection A and Collection C. The collection B is loaded (I can see it by Redux Logs) but can't be seen in the app.
Those datas appears only if I change the component status (open/close a menu, for example).
Some code
Here's how I retrieve a collection with sub-collections:
export function setCompanyJobs(user) {
return {
type: "SET_COMPANY_JOBS",
payload: loadCompanyJobs(user),
};
}
Function that retrieve the main collection
export function loadCompanyJobs(user) {
return new Promise((resolve, reject) => {
let companyJobs = [];
db.collection("company").doc(user.selectedCompany).collection("jobs").get().then((jobs) => {
jobs.forEach((job) => {
loadJobLinkedServices(user, job).then((jobLinkedServices) => {
companyJobs.push({
id: job.id,
...
});
});
});
resolve(companyJobs);
}).catch(function (error) {
...
});
});
}
Function that retrieve all collection's sub-collections
export function loadJobLinkedServices(user, job){
return new Promise((resolve, reject) => {
let jobLinkedServices = [];
db.collection("company").doc(user.selectedCompany).collection("jobs").doc(job.id).collection("linkedServices").get().then((linkedServices) => {
linkedServices.forEach((linkedService) => {
jobLinkedServices.push({
id: linkedService.id,
...
});
});
resolve(jobLinkedServices)
}).catch(function (error) {
...
});
})
When you do
return new Promise((resolve, reject) => {
let companyJobs = [];
db.collection("company").doc(user.selectedCompany).collection("jobs").get().then((jobs) => {
jobs.forEach((job) => {
loadJobLinkedServices(user, job).then((jobLinkedServices) => {
companyJobs.push({
id: job.id,
...
});
});
});
resolve(companyJobs);
}).catch(function (error) {
...
});
});
nothing ensure that your Promise resolves only after ALL the queries triggered in the jobs.forEach() loop are done (i.e. the promises returned by the calls to the loadJobLinkedServices function have resolved).
I don't know reactjs but I think you can use the JavaScript Promise.all() method along the following lines:
return new Promise((resolve, reject) => {
let promises = [];
let companyJobs = [];
db.collection("company").doc(user.selectedCompany).collection("jobs").get().then((jobs) => {
jobs.forEach((job) => {
promises.push(loadJobLinkedServices(user, job));
});
Promise.all(promises).
then(results => {
//Loop over the results array to populate the companyJobs array
resolve(companyJobs);
})
}).catch(function (error) {
...
});
});
Also, don't forget to correctly chain your calls to the different asynchronous functions, i.e. something like:
query Collection A
THEN query Collection B
THEN query all sub-collections (with Promise.all())
THEN query Collection C
THEN set Loading Status Inactive
Finally, a last remark: Note that the get() method returns a promise, so I am not sure that you need to wrap the calls to the get() method into some new Promises (Again, I am not versed in reactjs, so this remark may be wrong).
In other words, I think you could do something like the following (for example for the loadJobLinkedServices function):
export function loadJobLinkedServices(user, job){
let jobLinkedServices = [];
return db.collection("company").doc(user.selectedCompany).collection("jobs").doc(job.id).collection("linkedServices").get()
.then((linkedServices) => {
linkedServices.forEach((linkedService) => {
jobLinkedServices.push({
id: linkedService.id,
...
});
});
return jobLinkedServices;
}).catch(function (error) {
...
});
})

React Chrome extension and Promises

I am writing a Chrome extension in ReactJS.
I am looping through an array of URLs and trying to get the the HTML content of those pages.
this.state.advertData.map(function(e, i) {
common.updateTabUrl(e.url).then((tab) => {
common.requestHTML(tab).then((response) => {
console.log(response.content);
})
});
})
common.js:
let requestHTML = function(tab) {
return new Promise(function(resolve, reject) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tab.id, {'req': 'source-code'}, function (response) {
resolve(response)
})
})
})
}
let updateTabUrl = function(url) {
return new Promise(function(resolve, reject) {
let update = chrome.tabs.update({
url: url
}, function(tab) {
chrome.tabs.onUpdated.addListener(function listener (tabId, info) {
if (info.status === 'complete' && tabId === tab.id) {
chrome.tabs.onUpdated.removeListener(listener);
resolve(tab);
}
});
})
})
}
content_script.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
let response = '';
if (request.req === 'source-code') {
response = document.documentElement.innerHTML;
}
sendResponse({content: response});
});
My issue is that the response.content always seems to be the same. More importantly, the tab that updates seems to only ever display the last url in my array. I think it is a problem with the way I am handling Promises.
Any help is appreciated.
The problem with your code is that it doesn't wait for the previous URL to load before proceeding to the next one so only the last one gets actually loaded in a tab.
I suggest using 1) Mozilla's WebExtension polyfill, 2) await/async syntax, 3) executeScript that automatically runs when a tab is complete by default 4) a literal code string in executeScript so you don't need neither a separate file nor to declare the content script in manifest.json.
async function getUrlSourceForArray({urls, tabId = null}) {
const results = [];
for (const url of urls) {
await browser.tabs.update(tabId, {url});
const [html] = await browser.tabs.executeScript(tabId, {
code: 'document.documentElement.innerHTML',
});
results.push(html);
}
return results;
}
Invoking inside an async function:
const allHtmls = await getUrlSourceForArray({
urls: this.state.advertData.map(d => d.url),
tabId: null, // active tab
});
P.S. you can also open all the URLs at once in a new window in background, assuming there won't be more than say 10 URLs, otherwise you would risk exhausting the user's RAM.

How can I reverse data array of Firestore ? Angular 6

listItemAds() {
this.itemList = this.afs.collection<Class>('Collection');
this.itemList.snapshotChanges().subscribe(list => {
this.itemArray = [];
list.forEach(action => {
const data = action.payload.doc.data() as Class;
this.itemArray.push(data);
--> this.itemArray.reverse(); // I try use this.itemArray.reverse(data.idNumber) ==> error
});
});
console.log(this.itemArray);
}
I wanna reverse data from New data to Old data , I set idNumber in object ex:[1,2,3,4,5].
Note
You can use the orderBy query option in your collection call.
The Firebase documentation on ordering & limiting shows you how to use orderBy specifically.
Using the server to sort data results in better client performance.
this.itemList = this.afs.collection<Class>(
'Collection',
ref => ref.orderBy('idNumber', 'desc')
);
this.itemList.subscribe(list => {
console.log(list);
});

Angular2 : Iterate to get only array I decide

I need to iterate over json objects and array and for a specific thing I need return only array with my reviews.
I get and endpoint from my api like this :
{total_reviews: 206, average_score: 4.2,…}
average_score
:
4.2
reviews
:
[{meta_id: "259", rating_post_id: "5", rating_user_id: "1", rating_user_name: "christophe",…},…]
total_reviews
:
206
And in my angular service, I getting my endpoint like this :
getReviewsByPostId(paramsObj) {
let params = this.util.transformRequest(paramsObj);
return this.http.get(this.wpApiURL + '/reviews?' + params)
.map(res => {
this.reviews = res.json();
return this.reviews;
});
}
I also have a component :
loadReviews(postId) {
this.wp.getReviewsByPostId({post: postId}).subscribe(
data => {
console.log(data);
this.reviews = data;
},
error => {}
);
}
What's the method te return only reviews array in my angular app ? And not total_reviews and average_score
Thank you !
You can directly access the "reviews" value from your json response
Im not sure of the exact syntax but try one of the following
res.json().reviews
or
res.reviews
You could alternatively run a 'foreach' on your JSON response to only take the value of a specific key you require(in your case'reviews')
example:
getReviewsByPostId(paramsObj) {
let params = this.util.transformRequest(paramsObj);
return this.http.get(this.wpApiURL + '/reviews?' + params)
.map(res => {
this.reviews = res.json();
angular.forEach(this.reviews,function (key,value){
if(key==='reviews'){
//store value in an array or any other data container
}
});
// return array/dataContainer;
});
}

Resources