Facebook FQLproblem with javascript sdk - facebook-graph-api

Hey everyone,
i do the following query to get a user statuses:
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM statuses WHERE uid = ' + userId
},
function(data) {
// do something with the response
}
);
It works great when the number of result are more than 0.
but when there are no results, the callback function is not called at all.
i need to know if there are 0 rows returning from this query, is there any way to do it?
Thanks :)

First of all, the statuses table does not exists. You should be using status table.
The callback is always called but you should properly check against empty objects. Just paste this on the Javascript Test Console:
<fb:login-button scope="read_stream">
Grant access to statuses
</fb:login-button>
<button onclick="getStatuses()">Get Statuses</button>
<script>
window.getStatuses = function() {
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM status WHERE uid = me() AND time < 315532800'
},
function(data) {
if(!isEmpty(data)) {
for(var key in data) {
var obj = data[key];
console.log(obj['message'])
}
} else {
console.log("data is empty")
}
});
};
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
</script>
Here I am checking for statuses before 1/1/1980 to insure that an empty result is returned. In your console you should note the data is empty response.

When there are no results from a query, you should be getting an empty array.
Also, there isn't a FQL table named "statuses", it's "status".

Related

How to update an item after being newly created in AWS DynamoDB and Amplify

I am trying to update a query in AWS Dynamo using AWS Amplify on top of Next.js.
My scenario is simple.
On page load, if there exists a user and the user has not visited a page before, a new object will be created with set values using SWR.
const fetchUserSite = async (owner, code) => {
try {
// Create site object if no site exists
if (userData == null) {
const siteInfo = {
id: uuidv4(),
code: parkCode,
owner: user?.username,
bookmarked: false,
visited: false,
}
await API.graphql({
query: createSite,
variables: {input: siteInfo},
authMode: 'AMAZON_COGNITO_USER_POOLS',
})
console.log(`${code} added for the first time`)
}
return userData || null
} catch (err) {
console.log('Site not added by user', data, err)
}
}
// Only call the fetchUserSite method if `user` exists
const {data} = useSWR(user ? [user?.username, parkCode] : null, fetchUserSite)
Currently, this works. The object is added to the database with the above attributes. HOWEVER, when I click a button to update this newly created object, I get an error of path: null, locations: (1) […], message: "Variable 'input' has coerced Null value for NonNull type 'ID!'"
This is my call to update the object when I click a button with the onClick handler "handleDBQuery".
const handleDBQuery = async () => {
await API.graphql({
query: updateSite,
variables: {
input: {
id: data?.id,
bookmarked: true,
owner: user?.username,
},
},
authMode: 'AMAZON_COGNITO_USER_POOLS',
})
console.log(`${name} Bookmarked`)
}
My hunch is that the updateSite query does not know about the createSite query on page load.
In short, how can I update an item after I just created it?
I looked into the code at master branch and follow along as you describe. I found that the data?.id here comes from a state variable and it is set only before the call to createSite. I suggest you try setId again using the data returned from the createSite
Try this
const fetchUserSite = async (owner, code) => {
try {
// Create site object if no site exists
if (userData == null) {
const siteInfo = {
id: uuidv4(),
code: parkCode,
owner: user?.username,
bookmarked: false,
visited: false,
}
const { data: newData } = await API.graphql({
query: createSite,
variables: {input: siteInfo},
authMode: 'AMAZON_COGNITO_USER_POOLS',
});
setId(newData.id); // <====== here (or setId(siteInfo.id))
console.log(`${code} added for the first time`)
return newData; // <======= and this, maybe? (you may have to modify the qraphql query to make it return the same item as in the listSite
}
return userData || null
} catch (err) {
console.log('Site not added by user', data, err)
}
}

How to access data of another persisted model of loopback from remote method of one persisted model?

'use strict';
module.exports = function (City) {
City.GetCurrentPopulation = function (req) {
var population;
City.app.models.Pupulation.find({where{id:req.id}}, //This line //gives me an error that cannot read property 'find' of undefined
function(req.res){
population=res.population;
});
response='Population for ' +req.cname ' is' +population;
req(null, response);
};
City.remoteMethod(
'GetCurrentPopulation', {
http: {
path: '/GetCurrentPopulation',
verb: 'GetCurrentPopulation'
},
returns: {
arg: 'startdate',
type: 'string'
}
}
);
There is a model city and i want to access another model like "population.find(some filters)" How to do this?
I have a remote method written in city model. Where i am trying to access population record as
var countryp=population.find(where{id:4});
var currentpopulation=countryp.Totalpopulation;
It gives an error population.find is not a function.
Please suggest way to do this.
City.app.models.Population can only work if you defined some relation between City & Population models. Otherwise it wont work that way. If there is no relation to the other model. You need to get a reference to the app object using
Try like this:
var app = require('../../server/server');
module.exports = function (City) {
var Population = app.models.Population;
City.GetCurrentPopulation = function(req) {
Population.find({where{id:req.id}}, function (err) {
if (err) {
return console.log(err);
} else {
// do something here
});
}
You can refer to the documentation here https://loopback.io/doc/en/lb3/Working-with-LoopBack-objects.html#using-model-objects

Ember - Within action, result is defined, returnvalue of same action logged in parent action is undefined? Why?

Quick and shortly I have following problem:
I have following two actions within a component in Ember:
createData: function(user) {
let collection = [];
for (let i = 0; i < user.posts.length; i++) {
let data = this.send('createSingleData',user.posts[i], user, 'post');
console.log(data);
collection.push(data);
}
return collection;
},
createSingleData: function(data, user, type) {
let entitySkeleton = {
name: data.place.name,
belongsTo: user.id,
position: {
data.place.location.longitude,
data.place.location.latitude
}
};
console.log(entitySkeleton);
return entitySkeleton;
}
the first log - within createSingleData, right before returning the logged value - writes the entitySkeleton as Object into the console - as expected.
However, the console.log(data) - within createData - writes 'undefined' to the console.
Is there any aspect of asynchrounosity I didn't respect?
P.S.:
I also logged any paramater within createSingleData, they are all set properly.
The variable collection also only gets pushed 'undefined'.
You cannot return the value from action, instead you can set property from the action.
how to return values from actions in emberjs
actions: {
PrintSomething: function() {
let obj = [{a: 'raj'}, {a: 'Prudvi'}, {a : 'thimappa'}]
console.log('before', obj);
this.send('returnSomething', obj);
console.log('after calling action', this.get('returnvalue'));
},
returnSomething: function(obj) {
obj.push({a: 'FSDFSDF'})
var data = obj;
this.set('returnvalue', data);
}
}

AWS S3 Bucket Upload using CollectionFS and cfs-s3 meteor package

I am using Meteor.js with Amazon S3 Bucket for uploading and storing photos. I am using the meteorite packges collectionFS and aws-s3. I have setup my aws-s3 connection correctly and the images collection is working fine.
Client side event handler:
'click .submit': function(evt, templ) {
var user = Meteor.user();
var photoFile = $('#photoInput').get(0).files[0];
if(photoFile){
var readPhoto = new FileReader();
readPhoto.onload = function(event) {
photodata = event.target.result;
console.log("calling method");
Meteor.call('uploadPhoto', photodata, user);
};
}
And my server side method:
'uploadPhoto': function uploadPhoto(photodata, user) {
var tag = Random.id([10] + "jpg");
var photoObj = new FS.File({name: tag});
photoObj.attachData(photodata);
console.log("s3 method called");
Images.insert(photoObj, function (err, fileObj) {
if(err){
console.log(err, err.stack)
}else{
console.log(fileObj._id);
}
});
The file that is selected is a .jpg image file but upon upload I get this error on the server method:
Exception while invoking method 'uploadPhoto' Error: DataMan constructor received data that it doesn't support
And no matter whether I directly pass the image file, or attach it as data or use the fileReader to read as text/binary/string. I still get that error. Please advise.
Ok, maybe some thoughts. I have done things with collectionFS some months ago, so take care to the docs, because my examples maybe not 100% correct.
Credentials should be set via environment variables. So your key and secret is available on server only. Check this link for further reading.
Ok first, here is some example code which is working for me. Check yours for differences.
Template helper:
'dropped #dropzone': function(event, template) {
addImage(event);
}
Function addImage:
function addImagePreview(event) {
//Go throw each file,
FS.Utility.eachFile(event, function(file) {
//Some Validationchecks
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var fsFile = new FS.File(image.src);
//setMetadata, that is validated in collection
//just own user can update/remove fsFile
fsFile.metadata = {owner: Meteor.userId()};
PostImages.insert(fsFile, function (err, fileObj) {
if(err) {
console.log(err);
}
});
};
})(file);
// Read in the image file as a data URL.
reader.readAsDataURL(file);
});
}
Ok, your next point is the validation. The validation can be done with allow/deny rules and with a filter on the FS.Collection. This way you can do all your validation AND insert via client.
Example:
PostImages = new FS.Collection('profileImages', {
stores: [profileImagesStore],
filter: {
maxSize: 3145728,
allow: {
contentTypes: ['image/*'],
extensions: ['png', 'PNG', 'jpg', 'JPG', 'jpeg', 'JPEG']
}
},
onInvalid: function(message) {
console.log(message);
}
});
PostImages.allow({
insert: function(userId, doc) {
return (userId && doc.metadata.owner === userId);
},
update: function(userId, doc, fieldNames, modifier) {
return (userId === doc.metadata.owner);
},
remove: function(userId, doc) {
return false;
},
download: function(userId) {
return true;
},
fetch: []
});
Here you will find another example click
Another point of error is maybe your aws configuration. Have you done everything like it is written here?
Based on this post click it seems that this error occures when FS.File() is not constructed correctly. So maybe this should be you first way to start.
A lot for reading so i hope this helps you :)

Refresh a webpage just once after 5 seconds

I'm looking for a JavaScript solution (or whatever else) that will refresh a webpage ONLY once, after 5 seconds it has been opened. Is this possible without being stuck in a refresh loop?
try this:
setTimeout(function ()
{
if (self.name != '_refreshed_'){
self.name = '_refreshed_';
self.location.reload(true);
} else {
self.name = '';
}
}, 5000);
You could do this in many different ways, but I think the easiest would be to add a query string to the url after the refresh, allowing us to tell if the refresh has already occurred:
//Function to get query string value. Source: http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx
function getQuerystring(key, default_){
if (default_==null) default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
//check if our query string is already set:
if(getQuerystring(r) !== 1){
setTimeout(function(){window.location.href = window.location.href + '?r=1'},5000)
}
If there is the possibility that a query string is already present, you will have to account for that and change the '?' to an '&'.
Sure, if you don't mind using jquery you can do it via an ajax call after waiting 5 seconds. Just throwing you some sample code:
How to wait 5 seconds with jQuery?
$(document).ready(function() {
// Get data
$.ajax({
url : '/tommyStockExchange/Data',
dataType : 'html',
data : {
'format' : 'H',
'type' : 'E'
},
success : function(data) {
$("#executions").html(data);
},
statusCode : {
404 : function() {
alert('executions url 404 :(');
}
}
});
});
Make it redirect to the same page with a different #hash and in JS only register the redirect if the hash isn't set.
You just need to pass some sort of data between page loads. This can be done in a multitude of ways — use a cookie, a URL query parameter, or something on the server side. Query parameter example:
if (!location.search.match(/(\?|&|^)stopRefreshing(=|&|$)/))
{
setTimeout(function ()
{
var search = location.search;
location.search = search ? search + '&stopRefreshing' : 'stopRefreshing';
}, 5000);
}
Demo: http://jsbin.com/ofawuz/edit