framework7 component page not working with real database query - javascript

In framework7 (latest version) there are some sample pages for e.g. page-loader-component.html. This page having -
<p>Hello {{name}}</p>
and at bottom, there is script
return {
data: function(){
return{
name: "Peter"
}
}
}
Now when the page is accessed, it displays - Hello Peter
Question is I want to fetch name from real database from my server. So I made this changes -
app.request.post(
'http://domain-name/page.php',
{userid: 2},
function(response){
var response = JSON.parse(response);
console.log(response); //console log shows {name: "Peter"}
return response
}
);
return {
data: function(){
return response //console log shows response is not defined
}
}
Now when try to access the page, it throws errors (in console) - ReferenceError: response is not defined. In console my request query is OK, it show - {name: "Peter"}
I did return response as well as tried replacing the position of function as well as tried many other possible fix suggested on stackoverflow.
I think one function is running before other one make finish database queries. I am not expert (just average). So please someone suggest.
I have also tried to access the page through routes.js as example given in request-and-load.html but still reference error.

return response is inside the data: section. The request is not, and they cannot reach each other.
Put the gathering of data inside the data function. You also want to save the response outside of the request function. To make sure the response variable is reachable. I'd also personally move the request itself to be defined in a separate location for usage outside of this one instances.
File: custom.js
requests = {
GetName: function () {
app.request.post(
'http://domain-name/page.php',
{ userid: 2 },
function (response) {
var response = JSON.parse(response);
console.log(response); //console log shows {name: "Peter"}
return response
}
);
},
GetNameDynamic: function (id) {
app.request.post(
'http://domain-name/page.php',
{ userid: id},
function (response) {
var response = JSON.parse(response);
console.log(response);
return response
}
);
}
}
Then inside the data: section call that function and save as a variable. Pass that in the data return.
data: function () {
// Must return an object
var result = requests.GetName();
return {
name: result.name,
}
},
There are other ways/locations to accomplish this. One being the async in the route as the other user mentioned.
In the routes array, just change the path and componentUrl to the correct ones.
{
path: '/post-entity-group/:type/:group/:public/',
async: function (routeTo, routeFrom, resolve, reject) {
var result = requests.GetName();
resolve(
{
componentUrl: './pages/post-entity.html',
},
{
context: {
name: result.name,
}
}
)
}
},

I think you have to pass by async routeto load page context (c.f. F7 doc)
You will be able to load datas via resolve callback
Maybe an example can help : async data for page

Related

How to access the trello API from within a powerup?

How can I make queries against the trello API from within a powerup? This seems like such an obvious question but it doesn't seem to be covered that I can find.
My simple powerup looks like this so far:
var boardButtonCallback = function(t){
return t.popup({
title: 'Tools',
items: [
{
text: 'Hide Duplicates',
callback: function(t){
var cardQueryCb = function(result){
console.log(result);
}
var cardQ = 'https://trello.com/1/boards/[board_id]/cards/all';
fetch(cardQ).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
});
return t.cards('id', 'name')
.then(cardQueryCb);
}
}
]
});
};
TrelloPowerUp.initialize({
'board-buttons': function(t, options){
return [{
text: 'Duplicates',
callback: boardButtonCallback
}];
}
});
The response object after the call to fetch says the call is unauthorized.
I would have thought that calling this code from within the context of the power up would be considered authorized. While I'm logged into trello, I'm able to put that address into my browser and get a valid response - how come the javascript call doesn't also result in a valid response?
More importantly, how can I get a successful response from that URL?
Since your power-up is run through an iframe, it's not actually coming from the Trello page itself so you need to specify your API key and token in the GET URL.
Example:
https://api.trello.com/1/boards/560bf4298b3dda300c18d09c?fields=name,url&key={YOUR-API-KEY}&token={AN-OAUTH-TOKEN}
The info for getting your API key and token can be found here: https://trello.readme.io/v1.0/reference#api-key-tokens

Getting x from remote sources and mirroring on to a list

Currently I have this, if with the full app it will create a post with my chosen parameters, however I am very new with vue.js, My aim is to be able to have a text file of such (or other way of storing (json etc)) the values, and then having the js script iterate through the file and display as cards, so for example in the file I would have
"Mark", "http://google.com", "5556", "image"
Or of course using json or similar, I'm up to what ever but my problem is, I don't know how to get values from a remote source and mirror it on to the document, can anyone help?, for clarity here's the snippet of code that I'm using
var app = new Vue({
el: '#app',
data: {
keyword: '',
postList: [
new Post(
'Name',
'Link',
'UID',
'Image'),
]
},
});
-- EDIT --
I'd like to thank the user Justin MacArthur for his quick answer, if you or anyone else doesn't mind answering another one of my painfully incompetent questions. This is the function that adds the cards in a nutshell
var Post = function Post(title, link, author, img) {
_classCallCheck(this, Post);
this.title = title;
this.link = link;
this.author = author;
this.img = img;
};
I can now get the data from the text file, meaning I could do, and assuming I have response defined (that being the http request) it'll output the contents of the file, how would I do this for multiple cards- as, as one would guess having a new URL for each variable in each set of four in each card is not just tedious but very inefficient.
new Post(
response.data,
)
The solution you're looking for is any of the AJAX libraries available. Vue used to promote vue-resource though it recently retired that support in favor of Axios
You can follow the instructions on the github page to install it in your app and the usage is very simple.
// Perform a Get on a file/route
axios.get(
'url.to.resource/path',
{
params: {
ID: 12345
}
}
).then(
// Successful response received
function (response) {
console.log(response);
}
).catch(
// Error returned by the server
function (error) {
console.log(error);
}
);
// Perform a Post on a file/route
// Posts don't need the 'params' object as the second argument is sent as the request body
axios.post(
'url.to.resource/path',
{
ID: 12345
}
).then(
// Successful response received
function (response) {
console.log(response);
}
).catch(
// Error returned by the server
function (error) {
console.log(error);
}
);
Obviously in the catch handler you'd have your error handing code, either an alert or message appearing on the page. In the success you could have something along the lines of this.postList.push(new Post(response.data.name, response.data.link, response.data.uid, response.data.image));
To make it even easier you can assign axios to the vue prototype like this:
Vue.prototype.$http = axios
and make use of it using the local vm instance
this.$http.post("url", { data }).then(...);
EDIT:
For your multi-signature function edit it's best to use the arguments keyword. In Javascript the engine defines an arguments array containing the parameters passed to the function.
var Post = function Post(title, link, author, img) {
_classCallCheck(this, Post);
if(arguments.length == 1) {
this.title = title.title;
this.link = title.link;
this.author = title.author;
this.img = title.img;
} else {
this.title = title;
this.link = link;
this.author = author;
this.img = img;
}
};
Be careful not to mutate the arguments list as it's a reference list to the parameters themselves so you can overwrite your variables easily without knowing it.

Ember Understand execution flow between route/controller

I have a "box" route/controller as below;
export default Ember.Controller.extend({
initialized: false,
type: 'P',
status: 'done',
layouts: null,
toggleFltr: null,
gridVals: Ember.computed.alias('model.gridParas'),
gridParas: Ember.computed('myServerPars', function() {
this.set('gridVals.serverParas', this.get('myServerPars'));
this.filterCols();
if (!this.get('initialized')) {
this.toggleProperty('initialized');
} else {
Ember.run.scheduleOnce('afterRender', this, this.refreshBox);
}
return this.get('gridVals');
}),
filterCols: function()
{
this.set('gridVals.layout', this.get('layouts')[this.get('type')]);
},
myServerPars: function() {
// Code to set serverParas
return serverParas;
}.property('type', 'status', 'toggleFltr'),
refreshBox: function(){
// Code to trigger refresh grid
}
});
My route looks like;
export default Ember.Route.extend({
selectedRows: '',
selectedCount: 0,
rawResponse: {},
model: function() {
var compObj = {};
compObj.gridParas = this.get('gridParas');
return compObj;
},
activate: function() {
var self = this;
self.layouts = {};
var someData = {attr1:"I"};
var promise = this.doPost(someData, '/myService1', false); // Sync request (Is there some way I can make this work using "async")
promise.then(function(response) {
// Code to use response & set self.layouts
self.controllerFor(self.routeName).set('layouts', self.layouts);
});
},
gridParas: function() {
var self = this;
var returnObj = {};
returnObj.url = '/myService2';
returnObj.beforeLoadComplete = function(records) {
// Code to use response & set records
return records;
};
return returnObj;
}.property(),
actions: {
}
});
My template looks like
{{my-grid params=this.gridParas elementId='myGrid'}}
My doPost method looks like below;
doPost: function(postData, requestUrl, isAsync){
requestUrl = this.getURL(requestUrl);
isAsync = (isAsync == undefined) ? true : isAsync;
var promise = new Ember.RSVP.Promise(function(resolve, reject) {
return $.ajax({
// settings
}).success(resolve).error(reject);
});
return promise;
}
Given the above setup, I wanted to understand the flow/sequence of execution (i.e. for the different hooks).
I was trying to debug and it kept hopping from one class to another.
Also, 2 specific questions;
I was expecting the "activate" hook to be fired initially, but found out that is not the case. It first executes the "gridParas" hook
i.e. before the "activate" hook. Is it because of "gridParas"
specified in the template ?
When I do this.doPost() for /myService1, it has to be a "sync" request, else the flow of execution changes and I get an error.
Actually I want the code inside filterCols() controller i.e.
this.set('gridVals.layout', this.get('layouts')[this.get('type')]) to
be executed only after the response has been received from
/myService1. However, as of now, I have to use a "sync" request to do
that, otherwise with "async", the execution moves to filterCols() and
since I do not have the response yet, it throws an error.
Just to add, I am using Ember v 2.0
activate() on the route is triggered after the beforeModel, model and afterModel hooks... because those 3 hooks are considered the "validation phase" (which determines if the route will resolve at all). To be clear, this route hook has nothing to do with using gridParas in your template... it has everything to do with callling get('gridParas') within your model hook.
It is not clear to me where doPost() is connected to the rest of your code... however because it is returning a promise object you can tack on a then() which will allow you to essentially wait for the promise response and then use it in the rest of your code.
Simple Example:
this.doPost().then((theResponse) => {
this.doSomethingWith(theResponse);
});
If you can simplify your question to be more clear and concise, i may be able to provide more info
Generally at this level you should explain what you want to archive, and not just ask how it works, because I think you fight a lot against the framework!
But I take this out of your comment.
First, you don't need your doPost method! jQuerys $.ajax returns a thenable, that can be resolved to a Promise with Ember.RSVP.resolve!
Next: If you want to fetch data before actually rendering anything you should do this in the model hook!
I'm not sure if you want to fetch /service1, and then with the response you build a request to /service2, or if you can fetch both services independently and then show your data (your grid?) with the data of both services. So here are both ways:
If you can fetch both services independently do this in your routes model hook:
return Ember.RSVP.hash({
service1: Ember.RSVP.resolve($.ajax(/*your request to /service1 with all data and params, may use query-params!*/).then(data => {
return data; // extract the data you need, may transform the response, etc.
},
service2: Ember.RSVP.resolve($.ajax(/*your request to /service2 with all data and params, may use query-params!*/).then(data => {
return data; // extract the data you need, may transform the response, etc.
},
});
If you need the response of /service1 to fetch /service2 just do this in your model hook:
return Ember.RSVP.resolve($.ajax(/*/service1*/)).then(service1 => {
return Ember.RSVP.resolve($.ajax(/*/service2*/)).then(service2 => {
return {
service1,
service2
}; // this object will then be available as `model` on your controller
});
});
If this does not help you (and I really think this should fix your problems) please describe your Problem.

Meteor js | Display Json in view via helper

Im struggling with an issue using Meteor JS.
I call an api wich return me a Json array wich look like the one returned on this url (I don't put the whole array here cause of the size): https://blockchain.info/address/12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?format=json&offset=0
I call it server side like :
if (Meteor.isServer) {
Meteor.methods({
getWalletPreviousTx: function() {
var url = "https://blockchain.info/address/12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?format=json&offset=0";
var result = Meteor.http.get(url);
if(result.statusCode==200) {
var tx = JSON.parse(result.content);
return tx;
} else {
console.log("Response issue: ", result.statusCode);
var errorJson = JSON.parse(result.content);
throwError("Couldn't fetch wallet balance from Blockchain, try again later !");
}
}
});
}
And i retrieve it to my view via an helper in a specific template :
Template.wallet.helpers({
addrTxs: function () {
Meteor.call('getWalletPreviousTx', function(err, tx) {
console.log(tx);
return [tx];
});
}
});
The console.log in the helper actually log my Json array wich mean it have access to it.
Now the part im struggling with is to retrieve this Json to my view, i've tried a lot of way and none of them works, actually i have this in my view :
<template name="wallet">
<table>
{{#each addrTxs}}
<ul>
{{> addrTx}}
</ul>
{{/each }}
</table>
</template>
The part of the Json I want to display is the "addr" and "value" of each transactions :
"inputs":[
{
"sequence":4294967295,
"prev_out":{
"spent":true,
"tx_index":97744124,
"type":0,
"addr":"1AWAsn8rhT555RmbMDXXqzrCscPJ5is5ja",
"value":50000,
"n":0,
"script":"76a914683d704735fd591ba9f9aebef27c6ef00cbd857188ac"
}
}
]
Fact is, i never managed to display anything from this Json array in my view, even puting directly this in my view doesn't show anything :
{{addrTxs}}
What am I doing wrong ? Can anyone help with this ?
Thanks for reading.
----------------------- Edit ---------------------
I think the problem is more that my helper and template are loaded before the api call is finished (because the console.log appear in my console like 3seconds after my page is rendered). How can i make my helper wait until the api call is finished before rendering it in the view ? I use iron router.
I have tried to add a waitOn action on my route in order to wait until my api call is finished :
Router.route('/wallet', {
name: 'wallet',
template: 'wallet',
loadingTemplate: 'loading',
waitOn: function () {
Meteor.call('getWalletPreviousTx', function(error, result) {
if(!error) {
Ready.set(result)
}
});
return [
function () { return Ready.get(); }
];
},
action: function () {
if (this.ready())
this.render();
else
this.render('loading');
}
});
The above code with the waitOn action seems to work (i have no errors) but i don't know the way to display in my view the specific result from :
if(!error) {
Ready.set(result)
}
Transactions are contained in tx.txs, iterates through that.
Template.wallet.helpers({
addrTxs: function () {
Meteor.call('getWalletPreviousTx', function(err, tx) {
console.log(tx);
return tx.txs;
});
}
});
You're right, you need to use the sessions variables with async call.
First, call method on created :
Template.wallet.created = function () {
Meteor.call('getWalletPreviousTx', function(err, tx) {
console.log(tx.txs);
Session.set('tx', tx.txs);
});
};
Helper should look like this :
Template.wallet.helpers({
addrTxs: function () {
return Session.get('tx');
}
});

ExpressJS why is my GET method called after my DELETE method?

In my express app, when the DELETE method below is called, the GET method is immediately called after and it's giving me an error in my angular code that says it is expected an object but got an array.
Why is my GET method being called when i'm explicitly doing res.send(204); in my DELETE method and how can I fix this?
Server console:
DELETE /notes/5357ff1d91340db03d000001 204 4ms
GET /notes 200 2ms - 2b
Express Note route
exports.get = function (db) {
return function (req, res) {
var collection = db.get('notes');
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
};
};
exports.delete = function(db) {
return function(req, res) {
var note_id = req.params.id;
var collection = db.get('notes');
collection.remove(
{ _id: note_id },
function(err, doc) {
// If it failed, return error
if (err) {
res.send("There was a problem deleting that note from the database.");
} else {
console.log('were in delete success');
res.send(204);
}
}
);
}
}
app.js
var note = require('./routes/note.js');
app.get('/notes', note.get(db));
app.post('/notes', note.create(db));
app.put('/notes/:id', note.update(db));
app.delete('/notes/:id', note.delete(db));
angularjs controller
$scope.delete = function(note_id) {
var note = noteService.get();
note.$delete({id: note_id});
}
angularjs noteService
angular.module('express_example').factory('noteService',function($resource, SETTINGS) {
return $resource(SETTINGS.base + '/notes/:id', { id: '#id' },
{
//query: { method: 'GET', isArray: true },
//create: { method: 'POST', isArray: true },
update: { method: 'PUT' }
//delete: { method: 'DELETE', isArray: true }
});
});
** UPDATE **
To help paint the picture, here's the angular error i'm getting:
Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array http://errors.angularjs.org/1.2.16/$resource/badcfg?p0=object&p1=array
I'm assuming that i'm getting this error because my delete method is calling my get method (somehow) and the get method returns the entire collection.
Server side
You're removing an element from a collection in your delete function. This is done asynchronously and calling your callback when it's finished.
During this time, other requests are executed, this is why your GET request is executed before your DELETE request is finished.
The same happens in your get function, you're trying to find an element from a collection and this function is too asynchronous.
But this is server side only and it is fine, it should work this way, your problem is located client side.
Client side
If you want to delete your note after you got it, you will have to use a callback function in your angular controller which will be called only when you got your note (if you need help on that, show us your noteService angular code).
This is some basic javascript understanding problem, actions are often made asynchronously and you need callbacks to have an execution chain.
Maybe try doing something like this:
$scope.delete = function(note_id) {
var note = noteService.get({ id: note_id }, function()
{
note.$delete();
});
}
Your code doesn't make sense though, why is there a get in the $scope.delete? Why not do as simply as following:
$scope.delete = function(note_id) {
noteService.delete({ id: note_id });
}
Error
I think you get this error because of what your server sends in your exports.delete function. You're sending a string or no content at all when angular expects an object (a REST API never sends strings). You should send something like that:
res.send({
results: [],
errors: [
"Your error"
]
});

Categories

Resources