I have partially got this starter kit from prismic working, but I am having trouble modifying it. Currently the project outputs everything, and I would like to output different collections in different lists.
I am very new to express, which is what this is using. I am not sure how to use the prismic query in this case to output a separate list for each collection or at least specified collections?
The predicate query according to the prismic api that works is this [:d = at(document.tags, ["ktblog"])]
Here is the EJS template where my list is being outputted
<ul id="list">
<% for(var i=0; i<docs.results.length; i++) { %>
<li>
<a href="<%= ctx.linkResolver(ctx, docs.results[i]) %>">
<%= docs.results[i].slug %>
</a>
</li>
<% } %>
</ul>
There is a index.js file
var prismic = require('../prismic-helpers');
// -- Display all documents
exports.index = prismic.route(function(req, res, ctx) {
ctx.api.form('everything').set("page", req.param('page') || "1").ref(ctx.ref).submit(function(err, docs) {
if (err) { prismic.onPrismicError(err, req, res); return; }
res.render('index', {
docs: docs
});
});
});
// -- Display a given document
exports.detail = prismic.route(function(req, res, ctx) {
var id = req.params['id'],
slug = req.params['slug'];
prismic.getDocument(ctx, id, slug,
function(err, doc) {
if (err) { prismic.onPrismicError(err, req, res); return; }
res.render('detail', {
doc: doc
});
},
function(doc) {
res.redirect(301, ctx.linkResolver(ctx, doc));
},
function(NOT_FOUND) {
res.send(404, 'Sorry, we cannot find that!');
}
);
});
// -- Search in documents
exports.search = prismic.route(function(req, res, ctx) {
var q = req.query['q'];
if(q) {
ctx.api.form('everything').set("page", req.param('page') || "1").ref(ctx.ref)
.query('[[:d = fulltext(document, "' + q + '")]]').submit(function(err, docs) {
if (err) { prismic.onPrismicError(err, req, res); return; }
res.render('search', {
docs: docs,
url: req.url
});
});
} else {
res.render('search', {
docs: null,
url: req.url
});
}
});
and there is a prismic helper file
var Prismic = require('prismic.io').Prismic,
Configuration = require('./prismic-configuration').Configuration,
http = require('http'),
https = require('https'),
url = require('url'),
querystring = require('querystring');
// -- Helpers
exports.getApiHome = function(accessToken, callback) {
Prismic.Api(Configuration.apiEndpoint, callback, accessToken);
};
exports.getDocument = function(ctx, id, slug, onSuccess, onNewSlug, onNotFound) {
ctx.api.forms('everything').ref(ctx.ref).query('[[:d = at(document.id, "' + id + '")]]').submit(function(err, documents) {
var results = documents.results;
var doc = results && results.length ? results[0] : undefined;
if (err) onSuccess(err);
else if(doc && (!slug || doc.slug == slug)) onSuccess(null, doc)
else if(doc && doc.slugs.indexOf(slug) > -1 && onNewSlug) onNewSlug(doc)
else if(onNotFound) onNotFound()
else onSuccess();
});
};
exports.getDocuments = function(ctx, ids, callback) {
if(ids && ids.length) {
ctx.api.forms('everything').ref(ctx.ref).query('[[:d = any(document.id, [' + ids.map(function(id) { return '"' + id + '"';}).join(',') + '])]]').submit(function(err, documents) {
callback(err, documents.results);
});
} else {
callback(null, []);
}
};
exports.getBookmark = function(ctx, bookmark, callback) {
var id = ctx.api.bookmarks[bookmark];
if(id) {
exports.getDocument(ctx, id, undefined, callback);
} else {
callback();
}
};
// -- Exposing as a helper what to do in the event of an error (please edit prismic-configuration.js to change this)
exports.onPrismicError = Configuration.onPrismicError;
// -- Route wrapper that provide a "prismic context" to the underlying function
exports.route = function(callback) {
return function(req, res) {
var accessToken = (req.session && req.session['ACCESS_TOKEN']) || Configuration.accessToken || undefined
exports.getApiHome(accessToken, function(err, Api) {
if (err) { exports.onPrismicError(err, req, res); return; }
var ref = req.query['ref'] || Api.master(),
ctx = {
api: Api,
ref: ref,
maybeRef: ref == Api.master() ? undefined : ref,
oauth: function() {
var token = accessToken;
return {
accessToken: token,
hasPrivilegedAccess: !!token
}
},
linkResolver: function(ctx, doc) {
return Configuration.linkResolver(ctx, doc);
}
};
res.locals.ctx = ctx;
callback(req, res, ctx);
});
};
};
// -- OAuth routes
var redirectUri = function(req) {
return req.protocol + '://' + req.get('Host') + '/auth_callback';
};
exports.signin = function(req, res) {
exports.getApiHome(undefined, function(err, Api) {
if (err) { exports.onPrismicError(err, req, res); return; }
var endpointSpec = url.parse(Api.data.oauthInitiate);
endpointSpec.query = endpointSpec.query || {};
endpointSpec.query['client_id'] = Configuration.clientId;
endpointSpec.query['redirect_uri'] = redirectUri(req);
endpointSpec.query['scope'] = 'master+releases';
res.redirect(301, url.format(endpointSpec));
});
};
exports.authCallback = function(req, res) {
exports.getApiHome(undefined, function(err, Api) {
if (err) { exports.onPrismicError(err, req, res); return; }
var endpointSpec = url.parse(Api.data.oauthToken),
h = endpointSpec.protocol == 'https:' ? https : http,
postData = querystring.stringify({
'grant_type' : 'authorization_code',
'code': req.query['code'],
'redirect_uri': redirectUri(req),
'client_id': Configuration.clientId,
'client_secret': Configuration.clientSecret
});
var postOptions = endpointSpec;
postOptions.method = 'POST';
postOptions.headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
};
var postRequest = h.request(postOptions, function(response) {
var jsonStr = '';
response.setEncoding('utf8');
response.on('data', function (chunk) {
jsonStr += chunk;
});
response.on('end', function () {
var accessToken = JSON.parse(jsonStr)['access_token'];
if(accessToken) {
req.session['ACCESS_TOKEN'] = accessToken;
}
res.redirect(301, '/');
});
});
postRequest.write(postData);
postRequest.end();
});
};
exports.signout = function(req, res) {
delete req.session['ACCESS_TOKEN'];
res.redirect(301, '/');
};
You can specify a collection in the "form" call, instead of 'everything'. Typically if you have a 'foobar' collection, you can restrict any query to this collection this way:
ctx.api.form('foobar')...
You will have to make one call for each collection you want to display.
Related
The GET request to the Mongo works but the PUT is not working and I suspect that the path from controller to router is bad. I've tried using update() and findByIdAndUpdate() with no luck. I'm not hitting the router and if I do, I'm not seeing the data updated in Mongo. I'm using express, node and mongoose.
retail.controller.js
myApp.controller("RetailController", [
"RetailService",
"$routeParams",
"$http",
function(RetailService, $routeParams, $http) {
var self = this;
//self.isBusy = true;
self.getMovies = function(id) {
self.getDetails(id);
self.getApiMovies(id);
};
// Get data from MongoDB Movies Table
self.getDetails = function(id) {
$http({
method: "GET",
url: "/movies/data_store/" + id
}).then(function(response) {
self.productData = response.data[0];
console.log(self.productData);
});
};
self.getApiMovies = function(id) {
$http({
method: "GET",
url: "/movies/api/" + id
}).then(function(response) {
let data = response.data.product.item;
self.apiData = data;
});
};
self.updatePrice = function(id, data) {
$http({
method: "PUT",
url: "/update/" + id,
data
}).then(function(response) {
console.log(response);
});
};
}
]);
retail.router.js
var express = require("express");
var router = express.Router();
var MyRetail = require("../models/myretail.schema");
var request = require("request");
// Data route to API
router.get("/api/:id", function(req, res) {
var apiURL = "http://redsky.target.com/v2/pdp/tcin/13860428?price";
request(apiURL, function(error, response, body) {
if (error) {
console.log("error making Redsky API request");
res.sendStatus(500);
} else {
res.send(body);
}
});
}); // End route to API
// Data route to dB with :id
router.get("/data_store/:id", function(req, res) {
MyRetail.find({ id: req.params.id }, function(databaseQueryError, data) {
if (databaseQueryError) {
console.log("database query error", databaseQueryError);
res.sendStatus(500);
} else {
res.send(data);
}
});
}); // End data route to dB with :id
router.put("/update/:id", function(req, res) {
console.log(req.body.current_price.value);
console.log(req.body._id);
MyRetail.findByIdAndUpdate(
{ id: req.body._id },
{ $set: { "current_price.$.value": req.body.current_price.value } }
),
function(databaseQueryError, data) {
console.log(data);
if (databaseQueryError) {
console.log("database query error", databaseQueryError);
res.sendStatus(500);
} else {
res.send("data updated");
}
};
});
module.exports = router;
I'm looking for some help or a push in the right direction as to how to complete the PUT
Angularjs Service :
self.updatePrice = function(id, data) {
var URL = "/update/" + id;
$http.put( URL, data).then(function (response,error) {
if (error) {
console.log('error : '+JSON.stringify(error));
} else {
console.log('response : '+JSON.stringify(response));
}
})
};
Server Side :
router.put('/update/:id', function(req, res) {
console.log(req.body.current_price.value);
console.log(req.body._id);
MyRetail.update(
{ id: req.body._id },
{ $set: { "current_price.0.value": req.body.current_price.value } }
,function(databaseQueryError, data) {
console.log(data);
if (databaseQueryError) {
console.log("database query error", databaseQueryError);
res.sendStatus(500);
res.json({message : "data not updated"});
} else {
res.json({message : "data updated"});
}
});
});
Try this!Please variable/field name
for $ operator read documentation you need have current_price in find query.
I am pretty new to back end programming with JavaScript and have written some code to query a database and return the results as JSON. It seems to be working correctly in the browser, but my iOS code isn't getting any data from it. I have it running locally for now while testing. If you look in my Swift that gets the data from the URL, I'm getting the NO JSON from the print statement in the catch.
JavaScript
'use strict';
var util = require('util');
var sql = require("mssql");
var express = require('express');
var port = process.env.PORT || 1337;
var membershipNumber;
var queryString;
var app = express();
app.get('/membership/:number', function (req, res) {
console.log("\nPARAMS:");
console.log(req.params.number);
membershipNumber = req.params.number;
queryString = util.format('SELECT major_key, company, status, paid_thru FROM name WHERE major_key = \'%s\' and member_record = 1', membershipNumber);
console.log("\nQUERY:");
console.log(queryString);
res.setHeader('Content-Type', 'application/json');
res.set('Content-Type', 'application/json');
membershipStatusQuery(queryString, res);
});
app.get('/', function (req, res) {
var dictionary = [];
dictionary.push({
key: "none"
});
var jsonDict = JSON.stringify(dictionary);
res.setHeader('Content-Type', 'application/json');
res.set('Content-Type', 'application/json');
res.send(jsonDict);
});
function membershipStatusQuery(query, response) {
var config = {
server: 'DB_Server',
database: 'testDB',
user: 'sa',
password: 'password',
port: 1433
};
var connection = new sql.Connection(config);
connection.connect().then(function () {
var req = new sql.Request(connection);
req.query(query).then(function (recordset) {
connection.close();
response.send(results);
})
.catch(function (err) {
console.log(err);
connection.close();
response.send(err);
});
})
.catch(function (err) {
console.log(err);
response.send(err);
});
}
app.listen(port, function () {
console.log("Listening on port %s", port);
});
RESULTS
[{"major_key":"0001354648","company":"Membership of David Metzgar","status":"A","paid_thru":"2017-10-31T00:00:00.000Z"}]
iOS Swift Code
Class to get JSON from URL:
import UIKit
class GetJSON: NSObject {
func getJSONFrom(urlString: String) -> JSON {
let url = URL(string: urlString)
var data = Data()
do {
data = try Data(contentsOf: url!)
} catch {
print("No JSON")
// TODO: Display error
}
let json = JSON(data: data)
return json
}
}
Method from another class to use JSON:
func getQueryResultsJSON() {
print("http://localhost:1337/membership/\(memberNumberTextField.text!)")
// let jsonURL = "http://localhost:1337/membership/\(memberNumberTextField.text!)"
let jsonURL = "http://localhost:1337/membership/0001354648"
let getJSON = GetJSON()
self.resultsArray = getJSON.getJSONFrom(urlString: jsonURL)
if let dictionary = resultsArray?[0].dictionaryObject {
if let status = dictionary["status"] {
if status as! String == "A" {
print(dictionary)
print("Provided membership is active")
// membership is active
// TODO: save info and display membership card
} else {
print(dictionary)
print("Provided membership is NOT active")
// membership is not active
// TODO: display alert
}
} else {
print("DOESN'T EXIST!")
// membership number does not exist
// TODO: display alert
}
} else {
print("NOTHING!")
}
}
let url = NSURL(string: "your url")!
let request = NSMutableURLRequest(url: url as URL)
// request.httpMethod = "POST"
// request.httpBody = jsonData
//request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
if error != nil {
return
}
do {
let userObject = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: String]
if userObject != nil {
// do something
}
} catch let jsonError {
print(jsonError)
print(String(data: data!, encoding: String.Encoding.utf8)!)
}
}
task.resume()
In my database.js I have
var Mysql = require('Mysql');
var Jwt = require('jsonwebtoken');
var bcrypt = require('bcrypt');
var supersecretkey = 'JMDub_Super_Secret_key';
var config = require('./config');
var signupErrors = require('./Signuperrors.js');
var sucessMsg = require('./SucessMessages.js');
var App_errors = require('./error.js');
var query = require('./queryDB.js');
var connection = Mysql.createConnection({
"host": "******",
"user": "****",
"password": "***",
"database": "***"
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
//Sign Up Methods
var createUser = function createwithCredentails(post,callback) {
bcrypt.hash(post.password, 10, function(err, hash){
//console.log('Cache Hash : +',hash);
var createUserQuery = connection.query('INSERT INTO users SET ?',{"email":post.email,"password":hash,"username":post.username},function(err,result){
if (err) {
if (err.code == 'ER_DUP_ENTRY') {
//console.log(err.code);
callback(signupErrors.error_5000);
}
else callback(App_errors.error_1003);
}
if (result) {
callback(sucessMsg.success_signup);
}
});
});
}
//connection.query('SELECT * FROM Users Where Username = '' AND Password = ''');
var validateUser = function ValidateUserWithUserNameAndPassword(post,callback) {
var UserCheckQuery = connection.query('SELECT * FROM users WHERE email="'+post.email+'"',function(err, results, fields) {
if (err){
console.log(err);
callback(App_errors.error_1000);
}
if (results.length == 1) {
//console.log(results[0].password,post.password);
var givenPassword = post.password;
var DBhash = results[0].password;
bcrypt.compare(givenPassword, DBhash,function(err, res) {
if (res) {
console.log('Password matched');
var token = Jwt.sign({"email":post.email,"username":post.username},supersecretkey, {
expiresIn: 60*60*5 // expires in 5 hours
});
callback({
message:{
"success":1,
"description":"sucessfully logged in - please cache the token for any queries in future",
"environment":"test",
"errorCode":null
},
"token":token
});
}
if (!res) {
console.log('password doesnt match');
callback(signupErrors.error_6000);
}
if (err) {
console.log('Error Comparing Passwords');
callback(App_errors.error_1004);
}
});
}
else{
callback(signupErrors.error_6000);
}
});
};
var isauthenticate = function isauthenticated(post,route,callback) {
if (post.headers.token) {
Jwt.verify(post.headers.token, supersecretkey, function(err, decoded) {
if (decoded) {
//console.log(decoded);
//From this part the user is Sucessully Authenticated and autherization params can be extracted from token if required
//Write Business Logic in future as per the requirement
//Operation 1 - Update Profile
//Profile Details consists of {1.first name 2.last name 3. profile pictur(base 64 encoded) 4.further settings in future that can be added to DB if required}
if (route == '/update-profile') {
query.updateProfile(connection,decoded.email,post.body,function(response) {
callback(response);
});
}
//callback({"message":"is a valid token"});
}
if (decoded == null) {
console.log('is not a valid token');
//callback(App_errors.error_1000);
}
if (err) {
console.log('error verifying token');
callback(App_errors.error_1000);
}
});
}
else{
callback(App_errors.error_1001);
}
};
module.exports = {
validateUser:validateUser,
createUser:createUser,
isauthenticate:isauthenticate,
connection:connection
}
I am exporting connection object to queryDB.js file. But when I try to log the exported connection object I get undefined object. Why is this happening?
When I pass connection object as function argument, everything works fine. Not sure why?
below is queryDB.js file
var errors = require('./error.js')
var Dbconnection = require('./Database.js').connection;
var updateProfile = function profiledata(connection,email,data,callback) {
console.log(Dbconnection);
if ((!data)|| (Object.keys(data).length < 1)) {
//console.log(data);
callback(errors.error_1001);
}
else{
callback({"message":"update Sucesss"});
//console.log(connection);
//var updateData = mapProfileDataTomodel(data);
//console.log(updateData);
connection.query('SELECT * FROM users WHERE email = "'+email+'"',function(err, result,feilds) {
if (err) throw err;
if (result) {
console.log(result);
}
});
}
}
var mapProfileDataTomodel = function mapProfileDataTomodel(data) {
var profileDataModel = {};
for (var key in data) {
//console.log('looping and mapping data');
if (data.firstname) {
profileDataModel.firstname = data.firstname;
}
if (data.lastname) {
profileDataModel.lastname = data.lastname;
}
if (data.profilepic) {
profileDataModel.profilepic = data.profilepic;
}
}
return profileDataModel;
}
module.exports = {
updateProfile:updateProfile
}
I have commented out connection object log via function arguments.
So, Why I am unable to get the connection object that is exported? But I used the same exported connection object in my app.js file. It did work fine there.
var Attendance = require('../../../collections/attendance').Attendance;
var moment = require('moment');
module.exports = function(app) {
app.get('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.getByUser(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var job = d['attendance'];
if (typeof job != undefined) {
res.json(job);
console.log('This is it' + job['status']);
} else
res.json('No data Present', 200);
}
});
});
app.post('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.create(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var attendance = d['attendance'];
if (typeof job != undefined) {
console.log('Attendance record created' + attendance);
res.json(attendance);
} else
res.json('No data Present', 200);
}
});
});
}
This is the api code I to which I need to make the GET and POST request. But I have no idea how to do it.
It looks like your code is using express which would normally be good for building and API for your app. However to make a simple request to a third party api and staying in node.js why not try the request module which is great. https://www.npmjs.org/package/request
Your example does not show what the path of the request is or if you need any additinal headers etc but here is a simple example of a GET request using request.
var request = require('request');
function makeCall (callback) {
// here we make a call using request module
request.get(
{ uri: 'THEPATHAND ENDPOINT YOU REQUEST,
json: true,
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
}
},
function (error, res, object) {
if (error) { return callback(error); }
if (res.statusCode != 200 ) {
return callback('statusCode');
}
callback(null, object);
}
);
}
or jquery .ajax from a front end client direcct to your path
$.ajax({
url: "pathtoyourdata",
type: "GET",
})
.done(function (data) {
//stuff with your data
});
I'm attempting to post an image onto the twitter api, v1.1
I've tried just about all the example out there, and nothing seems to be able to post it.
include Posting images to twitter in Node.js using Oauth
I'm using the oauth library mentioned there, and I also had jsOauth, which I thought I'd give a shot according to https://gist.github.com/lukaszkorecki/1038408
Nothing has worked, and at this point I'm starting to lose hope on whether I can even do this.
function postStatusWithMedia(status, file) {
var err = new Object();
if(fs.existsSync(file) === false) {
err.message = "File not found :(";
parseTwitterError(err);
} else {
var oauth = OAuth(options = {
"consumerKey": consumer_key,
"consumerSecret": consumer_secret,
"accessTokenKey": access_token,
"accessTokenSecret": access_token_secret
});
callbacks = {
onSuccess : function() {
console.log('upload worked!')
},
onFailure : function() {
console.log('upload failed!');
console.dir(arguments);
}
},
uploadData = {
'status' : status,
'media' : Base64.encode(fs.readFileSync(file))
};
oauth.post('https://api.twitter.com/1.1/statuses/update_with_media.json',uploadData, callbacks.onSuccess, callbacks.onFailure);
return false;
}
}
If it can't be done, can you please explain why?
Otherwise, anything that could lead me to the right direction would be great.
var fs = require('fs');
var request = require('request');
var FormData = require('form-data');
var utf8 = require('utf8');
// Encode in UTF-8
status = utf8.encode(status);
var form = new FormData();
form.append('status', status)
form.append('media[]', fs.createReadStream(file));
// Twitter OAuth
form.getLength(function(err, length){
if (err) {
return requestCallback(err);
}
var oauth = {
consumer_key: consumer_key,
consumer_secret: consumer_secret,
token: access_token,
token_secret: access_token_secret
};
var r = request.post({url:"https://api.twitter.com/1.1/statuses/update_with_media.json", oauth:oauth, host: "api.twitter.com", protocol: "https:"}, requestCallback);
r._form = form;
r.setHeader('content-length', length);
});
function requestCallback(err, res, body) {
if(err) {
throw err;
} else {
console.log("Tweet and Image uploaded successfully!");
}
}
I ended up using request and node-form-data to manually construct a multipart/form-data request and send it with the status request, utf8 was for encoding the status into UTF-8, not doing so caused issues with '<3' and other characters.
I have not tested these code.Its from my colleague.sure the code is working.
Perhaps this will help.
//twitter_update_with_media.js
(function() {
var fs, path, request, twitter_update_with_media;
fs = require('fs');
path = require('path');
request = require('request');
twitter_update_with_media = (function() {
function twitter_update_with_media(auth_settings) {
this.auth_settings = auth_settings;
this.api_url = 'https://api.twitter.com/1.1/statuses/update_with_media.json';
}
twitter_update_with_media.prototype.post = function(status, imageUrl, callback) {
var form, r;
r = request.post(this.api_url, {
oauth: this.auth_settings
}, callback);
form = r.form();
form.append('status', status);
return form.append('media[]', request(imageUrl));
};
return twitter_update_with_media;
})();
module.exports = twitter_update_with_media;
}).call(this);
next file
//upload_to_twitter.js
var tuwm = new twitter_update_with_media({
consumer_key: TWITTER_OAUTH_KEY,
consumer_secret: TWITTER_OAUTH_SECRET,
token: access[0],
token_secret: access[1]
});
media_picture.picture = imageURL;
if (media_picture.picture) {
console.log('with media upload');
request.head(media_picture.picture,
function (error, response, body) {
if (!error && response.statusCode == 200) {
var image_size = response.headers['content-length'];
if (image_size > 2000000) { // 2mb max upload limit
console.log('greater than 2mb');
sendMessageWithoutImage(err, req, res, next, twit, wallpost, access);
} else {
console.log('less than 2mb');
console.log('twitter text', content);
tuwm.post(content, media_picture.picture, function(err, response) {
if (err) {
console.log('error', err);
return next(err);
}
error_parse = JSON.parse(response.body);
console.log('with media response', response.body);
if (error_parse.errors) {
console.log('have errors', error_parse);
res.json({
status: 500,
info: error_parse.errors[0].code + ' ' + error_parse.errors[0].message
});
} else {
res.json({
status: 200,
info: "OK",
id: response.id
});
}
});
}
}
});