Instafeed: skip retrieving video type posts from feed - image

I want to skip all video type posts from a feed that I'm gathering through the Instafeed JS plugin. Read from a few other posts that setting a filter would solve it but if I apply this (see below) I only get 2 images instead of 5. 1 of those 5 are a video type and the rest are image types. Not sure whats going on here?
var loadButton = document.getElementById('instafeed-loadmore');
var feed = new Instafeed({
get: 'user',
type: 'image',
limit: '5',
sortBy: 'most-recent',
resolution: 'standard_resolution',
userId: '',
accessToken: '',
template: '<div><img src="{{image}}" data-etc=""></div>',
filter: function(image) {
return image.type === 'image';
},
after: function() {
if (!this.hasNext()) {
loadButton.setAttribute('disabled', 'disabled');
}
},
});
loadButton.addEventListener('click', function() {
feed.next();
});

Maybe removing the resolution parameter should help. Also I dont think
type: 'image',
is a valid argument. I cant find it in the instafeed documentation as well.

TRy following
var feed = new Instafeed({
get: "user",
userId: "xxxx",
accessToken: "xxxx",
filter: function(image) {
if (image.type === "image") {
return false;
}
return true;
}
});
feed.run();

Related

importing medium articles into gatsby

I am trying to integrate my medium feed into gatsby and only want to select a few articles - not have the most recent ones. I was able to get the three most recent articles using this code:
index.config
mediumRssFeed:
"https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fmedium.com%2Ffeed%2F%40maxgraze",
shownArticles: 3,
Articles.js
const Articles = () => {
const MAX_ARTICLES = shownArticles
const { isIntroDone, darkMode } = useContext(Context).state
const [articles, setArticles] = useState()
const articlesControls = useAnimation()
// Load and display articles after the splashScreen sequence is done
useEffect(() => {
const loadArticles = async () => {
if (isIntroDone) {
await articlesControls.start({
opacity: 1,
y: 0,
transition: { delay: 1 },
})
fetch(mediumRssFeed, { headers: { Accept: "application/json" } })
.then(res => res.json())
// Feed also contains comments, therefore we filter for articles only
.then(data => data.items.filter(item => item.categories.length > 0))
.then(newArticles => newArticles.slice(0, MAX_ARTICLES))
.then(articles => setArticles(articles))
.catch(error => console.log(error))
}
}
loadArticles()
}, [isIntroDone, articlesControls, MAX_ARTICLES])
But I was hoping to query specific articles using gatsby-source-medium. However, it only returns 4 (and not even the most recent ones at that).
Is there a way to get all my articles via gatsby-source-medium? Otherwise, is there a way to "hard code" the articles I want? I'm not sure how to filter using the rss feed api. Thanks for yoru help!
As you suggested, there's a more native way using gatsby-source-medium but the documentation lacks good examples.
// In your gatsby-config.js
plugins: [
{
resolve: `gatsby-source-medium`,
options: {
username: `username/publication`,
},
},
]
Update:
It seems to be a known bug with Medium source and there's nothing we can do on our project. For further details:
gatsbyjs/gatsby#22491
A query like the following one will gather all posts from the user within the preview image:
query {
allMediumPost(sort: { fields: [createdAt], order: DESC }) {
edges {
node {
id
title
virtuals {
subtitle
previewImage {
imageId
}
}
author {
name
}
}
}
}
}

Vue Component not showing store data

I am building a trivia maker. I am currently working on the edit page for a question. The edit component, named EditQAForm, grabs the question and answers for that particular question and populates each of it's respective VueX store's form.
I am currently having trouble with the answers portion of this page. When the EditQAForm is mounted it calls the fetchQuestionAnswers, which retrieves all the answers for that particular question. It does this correctly, but then when I try to display any of the answers onto the page, it says that the form is empty despite me seeing in the Vue DevTools that it is not empty.
(Please note I deleted stuff that wasnt relevant to this. So assume all methods you see called do exist)
Here is the mounted for the EditQAForm:
mounted() {
//gets the params from the url
this.routeParams = this.$route.params;
//gets the answers that belong to this question
this.fetchQuestionAnswers(this.routeParams.question_id);
//not important for this problem
//get the question that needs to be edited
this.fetchQuestion(this.routeParams.question_id);
},
How I call it in the computed properties of the EditQAForm:
computed: {
...mapGetters('question', ['formQuestionRoundID', 'questions', 'questionFields']),
...mapGetters('answer', ['answerFields', 'answers']),
//Questions
questionForm: {
get() {
return this.questionFields;
},
},
//Answers
answerForm: {
get() {
return this.answerFields;
},
},
}
Here is the store for the answers
function initialState() {
return {
answers: [],
answer: null,
form: [
{
id: '',
title: '',
question_id: '',
round_id: '',
correct: false,
},
{
id: '',
title: '',
question_id: '',
round_id: '',
correct: false,
},
{
id: '',
title: '',
question_id: '',
round_id: '',
correct: false,
},
]
}
}
const getters = {
answers(state){
return state.answers;
},
answerFields(state){
return state.form;
},
loading(state){
return state.loading;
},
};
const actions = {
fetchQuestionAnswers({ commit, state }, question_id) {
console.log("Form outside axios:");
console.log(state.form);
commit('setLoading', true);
axios.get('/api/question/' + question_id + '/answers')
.then(response => {
commit('SET_ANSWERS_FORM', response.data);
commit('setLoading', false);
}).catch( error => {
console.log(error.response);
});
},
const mutations = {
SET_ANSWERS_FORM(state, answers){
for(let $i = 0; $i < answers.length; $i++)
{
state.form[$i] = {
id: answers[$i].id,
title: answers[$i].title,
question_id: answers[$i].question_id,
round_id: answers[$i].round_id,
correct: answers[$i].correct,
}
}
// state.answers = answers;
},
UPDATE_TITLE(state, payload){
state.form[payload.order].title = payload.title;
},
UPDATE_QUESTION_ID(state,payload){
state.form[payload.order].question_id = payload.questionID;
},
};
What I try outputting:
<div>
<h3 class="pb-3">Is first answer's title not empty?: {{!(answerForm[1].title === '')}}</h3>
<h3 class="pb-3">{{answerForm[0].title }}</h3>
<h3>{{answerForm}}</h3>
</div>
What shows on my screen, alongside what devtools tells me is inside the answerForm array:
I implemented the question portion in a very similar way. The only difference is that the form is not an array in the question store, but besides that it works fine. What am i doing wrong?
I think the problem is here:
state.form[$i] = {
If you use an index to update an array it won't trigger the reactivity system and you'll get a stale version of the rendered components. See https://v2.vuejs.org/v2/guide/list.html#Caveats
There are various ways to fix this. You could use Vue.set or alternatively just create am entirely new array.
Not entirely clear to me why you're doing all that copying in the first place rather than just using state.form = answers, which would also solve the problem.

Writing Structural Expectations with Jest

I am looking to write what I am calling structural expectations with Jest and I am not sure how this could be accomplished.
To start I have a graphql server and a database with a number of todo items. I currently have the following test that just returns true if the content within the database is the same as the response that I have written. I want to check instead that the response looks like an object with data that could be anything.
Here is the code that I have:
describe('To Do:', () => {
it('add todo items', async () => {
const response = await axios.post('http://localhost:5000/graphql', {
query: `
query {
getTodoItems {
message
id
dateCreated
dateDue
}
}
`
});
const { data } = response;
expect(data).toMatchObject({
data: {
getTodoItems: [
{
message: "message",
id: "5bd9aec8406e0a2170e04494",
dateCreated: "1540992712052",
dateDue: "1111111111"
},
{
message: "message",
id: "5bd9aeec60a9b2579882a308",
dateCreated: "1540992748028",
dateDue: "1111111111"
},
{
message: "new message",
id: "5bd9af15922b27236c91837c",
dateCreated: "1540992789836",
dateDue: "1111111111"
}
]
}
})
});
});
Now I want to write something like this, where there can be any number of returned items and they follow similar structuring:
describe('To Do:', () => {
it('add todo items', async () => {
const response = await axios.post('http://localhost:5000/graphql', {
query: `
query {
getTodoItems {
message
id
dateCreated
dateDue
}
}
`
});
const { data } = response;
expect(data).toMatchObject({
data: {
getTodoItems: [
{
message: expect.any(String),
id: expect.any(String),
dateCreated: expect.any(String),
dateDue: expect.any(String)
} // There needs to be unlimited additional items here
]
}
})
});
});
I have been looking throught the docs and I even tried nesting the expectations but I can't seem to get the desired response. Let me know what yo think or if I can clarify in any way.
I figured out the best way for me to do it. I would love to hear better answers. I wrote a function within the scope of the test as a jest.fn and then I called it. In that function, I made custom checks to parse the data that was received in the response. From there I added an expect function with the 'toHaveReturnedWith' method to see what the response of my custom function was and finishing out the test.
const addTodoResponse = jest.fn(() => {
// Custom parsing and check here
// Returns true or false
});
addTodoResponse();
expect(addTodoResponse).toHaveReturnedWith(true);
Are there better ways to do this out there?

Laravel vue show old data on update fields

So I've made update function for my component and it's working perfectly the only issue is I cannot show old data (if there is any) to the user,
This is what I have now:
As you see not only i can send my form data to back-end for update, but also I have the saved data already.
Code
export default {
data: function () {
return {
info: '', //getting data from database
profile: { //sending new data to back-end
photo: '',
about: '',
website: '',
phone: '',
state: '',
city: '',
user_id: '',
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
}
}
},
mounted: function() {
this.isLoggedIn = localStorage.getItem('testApp.jwt') != null;
this.getInfo();
},
beforeMount(){
if (localStorage.getItem('testApp.jwt') != null) {
this.user = JSON.parse(localStorage.getItem('testApp.user'))
axios.defaults.headers.common['Content-Type'] = 'application/json'
axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('testApp.jwt');
console.log()
}
},
methods: {
update() { // sending data to back-end
let user_id = this.user.id;
let photo = this.profile.photo;
let about = this.profile.about;
let website = this.profile.website;
let phone = this.profile.phone;
let state = this.profile.state;
let city = this.profile.city;
axios.put('/api/updateprofile/'+ user_id, {user_id, photo, about, website, phone, state, city}).then((response) => {
this.$router.push('/profile');
$(".msg").append('<div class="alert alert-success" role="alert">Your profile updated successfully.</div>').delay(1000).fadeOut(2000);
});
Vue.nextTick(function () {
$('[data-toggle="tooltip"]').tooltip();
})
},
getInfo: function() { //getting current data from database
let user_id = this.user.id;
axios.get('/api/show/'+ user_id).then((response) => {
this.info = response.data;
console.log(response);
});
},
}
}
Component sample field
// this shows my about column from database
{{info.about}}
// this sends new data to replace about column
<textarea name="about" id="about" cols="30" rows="10" class="form-control" v-model="profile.about" placeholder="Tentang saya..."></textarea>
Question
How to pass old data to my fields (sample above)?
Update
Please open image in big size.
This can be done by assigning this.profile the value of this.info on your Ajax response.
This way you will have input fields set up with original values.
function callMe() {
var vm = new Vue({
el: '#root',
data: {
profile:{},
info:{}
},
methods: {
getInfo: function() { //getting current data from database
this.info={about:"old data"}//your response here
this.profile=Object.assign({},this.info);
},
},
})
}
callMe();
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.11/dist/vue.js"></script>
<div id='root'>
<button #click="getInfo">Ajax Call click me</button>
Input <input v-model="profile.about"/>
<p>profile:{{this.profile}}</p>
<p>info: {{this.info}}</p>
</div>
The problem with the code is that after assigning new value info is not reactive anymore. You need to keep "info" like this in the start.
info: { // data from api
photo: '',
about: '',
website: '',
phone: '',
state: '',
city: '',
user_id: '',
}
And after fetching values from api update each value separately.
getInfo: function() { //getting current data from database
let user_id = this.user.id;
axios.get('/api/show/'+ user_id).then((response) => {
this.info.photo = response.data.photo;
this.info.about = response.data.about;
//all other values
console.log(response);
});
},
In your textarea you have a model profile.about, the way to show the "old data", is to assing to that model the data
in the create or mounted method you have to assing like
this.profile.about = this.info.about
this way profile.about will have the data stored in your db, that way if the user update it, the old data will be keep safe in this.info.about and the edited in this.profile.about

Updating Child Panels in Sencha Touch MVC App

Developing a Sencha Touch MVC app that pulls data from json store (thats set up to a DB pulling out content from a Wordpress Blog).
Everything works up until my "detail" panel. Instead of it listening to the TPL, its just dumping some data. The data looks similar to my blog post, but is filled with other code and doesn't make much sense.
Here is a lean version of my list:
myApp.views.PostListView = Ext.extend(Ext.Panel, {
postStore: Ext.emptyFn,
postList: Ext.emptyFn,
id:'postlistview',
layout: 'card',
initComponent: function () {
/* this.newButton = new Ext.Button({
text: 'New',
ui: 'action',
handler: this.onNewNote,
scope: this
});*/
this.topToolbar = new Ext.Toolbar({
title: 'All Posts',
/* items: [
{ xtype: 'spacer' },
this.newButton
],*/
});
this.dockedItems = [ this.topToolbar ];
this.postList = new Ext.List({
store: myApp.stores.postStore,
grouped: true,
emptyText: '<div style="margin:5px;">No notes cached.</div>',
onItemDisclosure: true,
itemTpl: '<div class="list-item-title">{title}</div>' +
'<div class="list-item-narrative"><small>{body}</small></div>',
});
this.postList.on('disclose', function (record) {
this.onViewPost(record);
}, this),
this.items = [this.postList];
myApp.views.PostListView.superclass.initComponent.call(this);
},
onViewPost: function (record) {
Ext.dispatch({
controller: myApp.controllers.masterController,
action: 'viewpost',
post: record
});
},
});
And here is the "detail" view that is called on disclosure:
myApp.views.PostSingleView = Ext.extend(Ext.Panel, {
title:'Single Post',
id:'postsingleview',
layout:'card',
style:'background:grey;',
initComponent: function () {
this.new1Button = new Ext.Button({
text: 'Back',
ui: 'back',
handler: this.onViewList,
scope: this,
dock:"left"
});
this.top1Toolbar = new Ext.Toolbar({
items: [
this.new1Button
],
title: 'Single Posts',
});
this.postSinglePanel = new Ext.Panel({
layout:'fit',
flex:1,
scroll: 'vertical',
style:'padding:10px;background:yellow;',
itemTpl: '<tpl for=".">' +
'<div class="list-item-narrative">{body}</div>' +
'</tpl>',
});
this.dockedItems = [ this.top1Toolbar, this.postSinglePanel ];
myApp.views.PostSingleView.superclass.initComponent.call(this);
},
onViewList: function () {
Ext.dispatch({
controller: myApp.controllers.masterController,
action: 'viewlist',
});
},
});
And here is the controller that its talking to:
Ext.regController('masterController', {
'index': function (options) {
if (!myApp.views.mainView) {
myApp.views.mainView = new myApp.views.MainView();
}
myApp.views.mainView.setActiveItem(
myApp.views.postView
);
},
'viewpost': function (options) {
myApp.views.postSingleView.postSinglePanel.update(options.post);
myApp.views.postView.setActiveItem(
myApp.views.postSingleView,
{ type: 'slide', direction: 'left' }
);
},
});
myApp.controllers.masterController = Ext.ControllerManager.get('masterController');
When the data comes out, it looks similar to this:
http://i.imgur.com/QlQG8.png
(the black boxes are "redacted" content, no error code there).
In closing, I believe that the controller is "dumping" the data into "MyApp.views.PostSingleView" rather than formatting it as I request in the TPL, though I'm not sure how to fix it. Any and all help MUCH appreciated!
UPDATE: As requested, here is the RegModel:
Ext.regModel("CategoryModel", {
fields: [
{name: "id", type: "int"},
{name: "title", type: "string"},
{name: "body", type: "string"},
],
hasMany: {
model: 'Post',
name: 'posts'
}
});
And here is a sample of the json:
{
   "status":"ok",
   "post":{
      "id":1037,
      "type":"post",
      "slug":"post-title",
      "url":"http:\/\/localhost:8888\/jsontest\/PostTitle\/",
      "status":"publish",
      "title":"Post Title",
      "title_plain":"Post Title",
      "content":"<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br \/>\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<\/p>\n<!-- PHP 5.x -->",
      "excerpt":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat [...]",
      "date":"2011-07-29 14:17:31",
      "modified":"2011-08-30 01:33:20",
      "categories":[
         {
            "id":87,
            "slug":"the-category",
            "title":"The Category",
            "description":"",
            "parent":17,
            "post_count":5
         }
      ],
      "tags":[
      ],
      "author":{
         "id":2,
         "slug":"tom",
         "name":"tom",
         "first_name":"tom",
         "last_name":"",
         "nickname":"",
         "url":"",
         "description":""
      },
      "comments":[
      ],
      "attachments":[
      ],
      "comment_count":0,
      "comment_status":"open"
   },
   "previous_url":"http:\/\/localhost:8888\/jsontest\/next-post\/",
   "next_url":"http:\/\/localhost:8888\/jsontest\/prev-post\/"
}
Use the tpl config option of the Ext.Panel not the itemTpl which doesn't exist.
As someone has mentioned before, be careful when using a Model instance and the update method, you will need to use the model's data property.
Try using this:
myApp.views.postSingleView.postSinglePanel.update(options.post.data);
the reason is that post does not actually expose the underlying data directly, you need to use the property data for that.
Also any particular reason why you are docking the postSinglePanel? I would be very careful using too many docked items as they are a known source of bugs and layout issues.
A simple way is to write your own method to update child panels (you can also see to override the default update method)
myApp.views.PostSingleView = Ext.extend(Ext.Panel, {
initComponent: function () {
// [...]
},
// [...]
myUpdate: function(data) {
this.postSinglePanel.update(data);
this.doComponentLayout(); // not sure if necessary...
}
});
and from your controller:
Ext.regController('masterController', {
// [...]
'viewpost': function (options) {
myApp.views.postSingleView.myUpdate(options.post.data); // note the .data
// [...]
},
});

Resources