I am using React Native and trying to read and then parse an RSS Feed. I am following this tutorial:
https://getsiphon.com/docs/build-a-youtube-browser/
I am using a bit of the code, but trying to use a different RSS Feed. For example:
https://fivejs.codeschool.com/feed.rss
Here is the specific code I am having trouble with:
getNews() {
var url = "https://fivejs.codeschool.com/feed.rss"
fetch(url)
.then((response) => response.text())
.then((responseText) => {
const doc = new DOMParser().parseFromString(responseText, "text/xml");
var items = doc.getElementsByTagName('item');
var objs = []
for (var i = 0; i < items.length; i++) {
objs.push({
title: items[i].childNodes[0]
})
}
console.log("yay! made it here")
console.log("objs length: ", objs.length)
console.log("objs: ", objs[0])
})
.catch((error) => {
console.log('Error fetching the feed: ', error);
});
}
Everything is fine up to the point where I am console logging out the objs array. In other words I see the yay! made it here message and I also see the objs.length message (25). Once it gets to the next part I do not see the first item in the array.
As a note, I am building my code and running it in a iOS simulator using Xcode. I am not sure if the debug output console has anything to do with it, but I can't imagine it would since it does output the other messages. I even tried to console.log the items[i].childNodes[0] in the for loop and didn't get any results.
Not sure is this would help you but following the same tutorial for my own project i had to check two main points to make everything work:
Check the labels on your XML, sometimes this will mess up your parsing.
Inside the loop you can select another property. For example, in my case trying to parse a blog rss, i got "Item" (like 12 items) and inside that i get "Title" so i did this:
var item = doc.getElementsByTagName('item');
for(i=0; i < item.length; i++){
var title = item[i].getElementsByTagName('title');
console.log(title[0].textContent);
}
With this you can create an element (maybe a dictionary?) and then push it inside your array.
I hope this helps you in some way.
Related
Description: I want to implement infinite scroll in React-Native with firebase and i want to paginate on collection group data for instant result in my app. Error is shown in screenshot.
My code:
var ref = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc').limit(5);
ref.get().then(snapshot => {
var posts = []
var lastVisible = snapshot.docs[snapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
});
var next = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc')
.startAfter(this.state.last_Visible)
.limit(5);
next.get()
.then(FirestoreDocumentSnapshot => {
var lastVisible = FirestoreDocumentSnapshot.docs[FirestoreDocumentSnapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
})
Please help, what i am doing wrong?
From a first look at the error and your code it seems like either the fields that you are referring to are empty, or the lastVisible should be an even number.
Try checking that you don't have empty fields in your docs and try removing the -1 from lastVisible.
Here you can check the proper way to use startAfter() which is the cause of your issue.
As you're sorting by time_stamp, you should specify that field in the query like so:
.startAfter(this.state.last_Visible.data().time_stamp)
Here is an example from the official documentation. (From the language tabs choose Node.js)
I'm using the Nodejs library for talking to Jira called jira-connector. I can get all of the boards on my jira instance by calling
jira.board.getAllBoards({ type: "scrum"})
.then(boards => { ...not important stuff... }
the return set looks something like the following:
{
maxResults: 50,
startAt: 0,
isLast: false,
values:
[ { id: ... } ]
}
then while isLast === false I keep calling like so:
jira.board.getAllBoards({ type: "scrum", startAt: XXX })
until isLast is true. then I can organize all of my returns from promises and be done with it.
I'm trying to reason out how I can get all of the data on pages with Ramda, I have a feeling it's possible I just can't seem to sort out the how of it.
Any help? Is this possible using Ramda?
Here's my Rx attempt to make this better:
const pagedCalls = new Subject();
pagedCalls.subscribe(value => {
jira.board.getAllBoards({ type:"scrum", startAt: value })
.then(boards => {
console.log('calling: ' + value);
allBoards.push(boards.values);
if (boards.isLast) {
pagedCalls.complete()
} else {
pagedCalls.next(boards.startAt + 50);
}
});
})
pagedCalls.next(0);
Seems pretty terrible. Here's the simplest solution I have so far with a do/while loop:
let returnResult = [];
let result;
let startAt = -50;
do {
result = await jira.board.getAllBoards( { type: "scrum", startAt: startAt += 50 })
returnResult.push(result.values); // there's an array of results under the values prop.
} while (!result.isLast)
Many of the interactions with Jira use this model and I am trying to avoid writing this kind of loop every time I make a call.
I had to do something similar today, calling the Gitlab API repeatedly until I had retrieved the entire folder/file structure of the project. I did it with a recursive call inside a .then, and it seems to work all right. I have not tried to convert the code to handle your case.
Here's what I wrote, if it will help:
const getAll = (project, perPage = 10, page = 1, res = []) =>
fetch(`https://gitlab.com/api/v4/projects/${encodeURIComponent(project)}/repository/tree?recursive=true&per_page=${perPage}&page=${page}`)
.then(resp => resp.json())
.then(xs => xs.length < perPage
? res.concat(xs)
: getAll(project, perPage, page + 1, res.concat(xs))
)
getAll('gitlab-examples/nodejs')
.then(console.log)
.catch(console.warn)
The technique is pretty simple: Our function accepts whatever parameters are necessary to be able to fetch a particular page and an additional one to hold the results, defaulting it to an empty array. We make the asynchronous call to fetch the page, and in the then, we use the result to see if we need to make another call. If we do, we call the function again, passing in the other parameters needed, the incremented page number, and the merge of the current results and the ones just received. If we don't need to make another call, then we just return that merged list.
Here, the repository contains 21 files and folders. Calling for ten at a time, we make three fetches and when the third one is complete, we resolve our returned Promise with that list of 21 items.
This recursive method definitely feels more functional than your versions above. There is no assignment except for the parameter defaulting, and nothing is mutated along the way.
I think it should be relatively easy to adapt this to your needs.
Here is a way to get all the boards using rubico:
import { pipe, fork, switchCase, get } from 'rubico'
const getAllBoards = boards => pipe([
fork({
type: () => 'scrum',
startAt: get('startAt'),
}),
jira.board.getAllBoards,
switchCase([
get('isLast'),
response => boards.concat(response.values),
response => getAllBoards(boards.concat(response.values))({
startAt: response.startAt + response.values.length,
})
]),
])
getAllBoards([])({ startAt: 0 }) // => [...boards]
getAllBoards will recursively get more boards and append to boards until isLast is true, then it will return the aggregated boards.
I've looked extensively and tried to modify multiple sample sets of codes found on different posts in Stack Overflow as well as template documents in Google App Maker, but cannot for the life of me get an export and en email function to work.
UserRecords table:
This is the area where the data is collected and reviewed, the populated table:
These are the data fields I am working with:
This is what the exported Sheet looks like when I go through the motions and do an export through the Deployment tab:
Lastly, this is the email page that I've built based on tutorials and examples I've seen:
What I've learned so far (based on the circles I'm going round in):
Emails seem mostly straight forward, but I don't need to send a message, just an attachment with a subject, similar to using the code:
function sendEmail_(to, subject, body) {
var emailObj = {
to: to,
subject: subject,
htmlBody: body,
noReply: true
};
MailApp.sendEmail(emailObj);
}
Not sure how to change the "body" to the exported document
To straight up export and view the Sheet from a button click, the closest I've found to a solution is in Document Sample but the references in the code speak to components on the page only. I'm not sure how to modify this to use the table, and also what to change to get it as a sheet instead of a doc.
This may seem trivial to some but I'm a beginner and am struggling to wrap my head around what I'm doing wrong. I've been looking at this for nearly a week. Any help will be greatly appreciated.
In it's simplest form you can do a Google sheet export with the following server script (this is based on a model called employees):
function exportEmployeeTable() {
//if only certain roles or individuals can perform this action include proper validation here
var query = app.models.Employees.newQuery();
var results = query.run();
var fields = app.metadata.models.Employees.fields;
var data = [];
var header = [];
for (var i in fields) {
header.push(fields[i].displayName);
}
data.push(header);
for (var j in results) {
var rows = [];
for (var k in fields) {
rows.push(results[j][fields[k].name]);
}
data.push(rows);
}
if (data.length > 1) {
var ss = SpreadsheetApp.create('Employee Export');
var sheet = ss.getActiveSheet();
sheet.getRange(1,1,data.length,header.length).setValues(data);
//here you could return the URL for your spreadsheet back to your client by setting up a successhandler and failure handler
return ss.getUrl();
} else {
throw new app.ManagedError('No Data to export!');
}
}
So here I have my code
notifull.get('/getNote', (request, response) => {
// START Get variables
var requestData = {
// location properties
subject: request.query.subject,
category: request.query.category,
subcategory: request.query.subcategory,
// easy way to get full reference string
referenceString: function() {
return `${this.subject}/${this.category}/${this.subcategory}`;
},
// pagination properties
pagePosition: Number(request.query.pagePosition),
// easy way to get limit number
paginationNumber: function() {
return (this.pagePosition - 1) * 2;
}
};
// DEBUG_PURPOSES response.send(requestData.referenceString());
// END Get variables
// START Construct index
var first = admin.firestore().collection(requestData.referenceString())
.orderBy("upvotes")
.limit(requestData.paginationNumber());
// DEBUG_PURPOSES response.send(first)
// END Construct index
// START Paginate
return first.get().then(function (documentSnapshots) {
// Get the last visible document
var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];
console.log("last", lastVisible);
// Construct a new query starting at this document,
// get the next 25 cities.
var next = admin.firestore().collection(requestData.referenceString())
.orderBy("upvotes")
.startAfter(lastVisible)
.limit(2);
response.send(next)
});
});
As you can see, I am attempting to Paginate using Cloud Firestore. If you'll notice, I've divided the code into sections, and the previous testing shows me the Construct Index and Get variables sections work. However, when I pulled the Paginate example from Firebase's own docs, adapted it to my code, and then tried to run, I was met with this error.
Cannot encode type ([object Object]) to a Firestore Value
UPDATE: After more testing, it seems that if I remove the startAfter line, it works fine.
According to firebase documentation, Objects of custom classes are not supported so in some languages like PHP, C++, Python and Node.js.
PLEASE HERE AS A REFERENCE.
https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects
So, I can advise to encode your objects to json and be decoding them to your custom classes when you download them from firebases.
This is for a phonegap angular app. I would have thought binding to the db query return, result.rows in my case would be possible but it seems like it is not. The only way I could get this to work was with the commented out code where I manually push the data into an array row by row. Is this the only way?
The actually error received by binding to .rows is: Error: Duplicates in a repeater are not allowed. Repeater: item in items key: undefined:undefined
The service:
// only portion of code shown
query: function (q) {
var d = $q.defer();
var db = this.getDb();
db.transaction(function (t) {
t.executeSql(q, [], function (tx, results) {
d.resolve(results);
}, function (err) {
d.reject(err);
});
}, function (err) {
d.reject(err);
}
);
return d.promise;
}
The controller is like this:
Sql.query('select * from DEMO').then(function (data) {
console.log(data);
//$scope.items = [];
//for (i = 0, l = data.rows.length; i < l; i++) {
//$scope.items.push(data.rows.item(i));
//}
$scope.items = data.rows; // this errors out
$scope.$safeApply();
});
The repeater is just a simple:
<div ng-repeat='item in items'>{{item.id}} {{item.data}}</div>
Based on the error message it looks like you have more than one undefined item in the data.rows array.
Your working code uses data.rows.item(i) is that creating an new empty object instead of undefined? Try changing data.rows.item(i) to data.rows[i] in your working code does that break as well?
Assuming you are using angular 1.1.5 here are some options:
Use your current workaround
Downgrade to 1.1.4 or to the current stable 1.0.7. I think 1.1.4 will work based on a broken version with 1.1.5 and a working version with 1.1.4.
Remove any duplicate undefined rows from data.rows
Note: For others having a similar type of error Angular generates a $$hashKey to objects when doing an ng-repeat. This error indicates the same object is in the array (with the same $$hashKey) and is not allowed in 1.1.5 (and later?).
See this blog post and google groups post for more info. Also this pull request looks related so I'm not sure if this behavior is intended going forward though it appears to have been fixed in the past.